diff --git a/CMakeLists.txt b/CMakeLists.txt index 435fc77..df22608 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -96,6 +96,10 @@ add_executable(AssetViewer "") target_link_libraries(AssetViewer PRIVATE Engine) target_include_directories(AssetViewer PRIVATE src/AssetViewer) +add_executable(Benchmark "") +target_link_libraries(Benchmark PRIVATE Engine) +target_include_directories(Benchmark PRIVATE src/Benchmark) + if(MSVC) add_definitions(-D_CRT_SECURE_NO_WARNINGS) target_compile_options(Engine PUBLIC /std:c++20 /Zi /MP14 /W4 /wd4505) diff --git a/allcull.png b/allcull.png new file mode 100644 index 0000000..d650afe Binary files /dev/null and b/allcull.png differ diff --git a/allnocull.png b/allnocull.png new file mode 100644 index 0000000..d4a6b53 Binary files /dev/null and b/allnocull.png differ diff --git a/benchmark.py b/benchmark.py new file mode 100644 index 0000000..5ec632e --- /dev/null +++ b/benchmark.py @@ -0,0 +1,4 @@ +import subprocess + +subprocess.run(['build/Benchmark.exe'], cwd='build') +subprocess.run(['build/Benchmark.exe', 'NOCULL'], cwd='build') \ No newline at end of file diff --git a/plots.py b/plots.py new file mode 100644 index 0000000..12e7695 --- /dev/null +++ b/plots.py @@ -0,0 +1,62 @@ +import pandas as pd +import matplotlib.pyplot as plt + +df = pd.read_csv('build/stats.csv') +noculldf = pd.read_csv('build/statsNOCULL.csv') + +fig, ax = plt.subplots() + +scaled_reltime = df['RelTime'] / 10**9 + +scaled_FrameTime = df['FrameTime'].rolling(window=100).mean() / 10**9 +scaled_CACHED = df['CACHED'].rolling(window=100).mean() / 10**9 +scaled_MIPGEN = df['MIPGEN'].rolling(window=100).mean() / 10**9 +scaled_DEPTHCULL = df['DEPTHCULL'].rolling(window=100).mean() / 10**9 +scaled_VISIBILITY = df['VISIBILITY'].rolling(window=100).mean() / 10**9 +scaled_LIGHTCULL = df['LIGHTCULL'].rolling(window=100).mean() / 10**9 +scaled_BASE = df['BASE'].rolling(window=100).mean() / 10**9 + +ax.plot(scaled_reltime, scaled_FrameTime, label='Frame Time') +ax.plot(scaled_reltime, scaled_CACHED, label='CACHED') +ax.plot(scaled_reltime, scaled_MIPGEN, label='MIPGEN') +ax.plot(scaled_reltime, scaled_DEPTHCULL, label='DEPTHCULL') +ax.plot(scaled_reltime, scaled_VISIBILITY, label='VISIBILITY') +ax.plot(scaled_reltime, scaled_LIGHTCULL, label='LIGHTCULL') +ax.plot(scaled_reltime, scaled_BASE, label='BASE') + + + +ax.set_xlabel('Application Time (ms)') +ax.set_ylabel('Render Times (ms)') + +ax.legend() + +fig.savefig('allcull.png') + +nocullfig, nocullax = plt.subplots() + +nocullscaled_reltime = noculldf['RelTime'] / 10**9 + +nocullscaled_FrameTime = noculldf['FrameTime'].rolling(window=100).mean() / 10**9 +nocullscaled_CACHED = noculldf['CACHED'].rolling(window=100).mean() / 10**9 +nocullscaled_MIPGEN = noculldf['MIPGEN'].rolling(window=100).mean() / 10**9 +nocullscaled_DEPTHCULL = noculldf['DEPTHCULL'].rolling(window=100).mean() / 10**9 +nocullscaled_VISIBILITY = noculldf['VISIBILITY'].rolling(window=100).mean() / 10**9 +nocullscaled_LIGHTCULL = noculldf['LIGHTCULL'].rolling(window=100).mean() / 10**9 +nocullscaled_BASE = noculldf['BASE'].rolling(window=100).mean() / 10**9 + +nocullax.plot(nocullscaled_reltime, nocullscaled_FrameTime, label='Frame Time') +nocullax.plot(nocullscaled_reltime, nocullscaled_CACHED, label='CACHED') +nocullax.plot(nocullscaled_reltime, nocullscaled_MIPGEN, label='MIPGEN') +nocullax.plot(nocullscaled_reltime, nocullscaled_DEPTHCULL, label='DEPTHCULL') +nocullax.plot(nocullscaled_reltime, nocullscaled_VISIBILITY, label='VISIBILITY') +nocullax.plot(nocullscaled_reltime, nocullscaled_LIGHTCULL, label='LIGHTCULL') +nocullax.plot(nocullscaled_reltime, nocullscaled_BASE, label='BASE') + +nocullax.set_xlabel('Application Time (ms)') +nocullax.set_ylabel('Render Times (ms)') + +nocullax.legend() + +nocullfig.savefig('allnocull.png') + diff --git a/src/Benchmark/CMakeLists.txt b/src/Benchmark/CMakeLists.txt new file mode 100644 index 0000000..038a7ae --- /dev/null +++ b/src/Benchmark/CMakeLists.txt @@ -0,0 +1,5 @@ +target_sources(Benchmark + PUBLIC + main.cpp + PlayView.h + PlayView.cpp) \ No newline at end of file diff --git a/src/Benchmark/PlayView.cpp b/src/Benchmark/PlayView.cpp new file mode 100644 index 0000000..f0a14e1 --- /dev/null +++ b/src/Benchmark/PlayView.cpp @@ -0,0 +1,63 @@ +#include "PlayView.h" +#include "Window/Window.h" +#include +#include + +using namespace Seele; + +PlayView::PlayView(Gfx::PGraphics graphics, PWindow window, const ViewportCreateInfo& createInfo, std::string dllPath, bool useMeshCulling) + : GameView(graphics, window, createInfo, dllPath) { + getGlobals().useDepthCulling = useMeshCulling; + queryThread = std::thread([&]() { + PRenderGraphResources res = renderGraph.getResources(); + Gfx::PPipelineStatisticsQuery cachedQuery = res->requestQuery("CACHED_QUERY"); + Gfx::PPipelineStatisticsQuery depthQuery = res->requestQuery("DEPTH_QUERY"); + Gfx::PPipelineStatisticsQuery baseQuery = res->requestQuery("BASEPASS_QUERY"); + Gfx::PPipelineStatisticsQuery lightCullQuery = res->requestQuery("LIGHTCULL_QUERY"); + Gfx::PPipelineStatisticsQuery visibilityQuery = res->requestQuery("VISIBILITY_QUERY"); + Gfx::PTimestampQuery timeQuery = res->requestTimestampQuery("TIMESTAMP"); + std::ofstream stats(fmt::format("stats{}.csv", useMeshCulling ? "" : "NOCULL")); + stats << std::fixed << std::setprecision(0); + stats << "RelTime," + << "CachedIAV,CachedIAP,CachedVS,CachedClipInv,CachedClipPrim,CachedFS,CachedCS,CachedTS,CachedMS," + << "DepthIAV,DepthIAP,DepthVS,DepthClipInv,DepthClipPrim,DepthFS,DepthCS,DepthTS,DepthMS," + << "BaseIAV,BaseIAP,BaseVS,BaseClipInv,BaseClipPrim,BaseFS,BaseCS,BaseTS,BaseMS," + << "LightCullIAV,LightCullIAP,LightCullVS,LightCullClipInv,LightCullClipPrim,LightCullFS,LightCullCS,LightCullTS,LightCullMS," + << "VisibilityIAV,VisibilityIAP,VisibilityVS,VisibilityClipInv,VisibilityClipPrim,VisibilityFS,VisibilityCS,VisibilityTS," + "VisibilityMS," + << "CACHED,MIPGEN,DEPTHCULL,VISIBILITY,LIGHTCULL,BASE,FrameTime" << std::endl; + float start = 0; + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + while (getGlobals().running) { + auto timestamps = timeQuery->getResults(); + auto cachedResults = cachedQuery->getResults(); + auto depthResults = depthQuery->getResults(); + auto baseResults = baseQuery->getResults(); + auto lightCullResults = lightCullQuery->getResults(); + auto visiblityResults = visibilityQuery->getResults(); + if (start == 0) { + start = timestamps[0].time; + } + stats << timestamps[0].time - start << "," << cachedResults << depthResults << baseResults << lightCullResults + << visiblityResults << timestamps[1].time - timestamps[0].time << "," << timestamps[2].time - timestamps[1].time << "," + << timestamps[3].time - timestamps[2].time << "," << timestamps[4].time - timestamps[3].time << "," + << timestamps[5].time - timestamps[4].time << "," << timestamps[6].time - timestamps[5].time << "," + << timestamps[6].time - timestamps[0].time << std::endl; + stats.flush(); + } + }); +} + +PlayView::~PlayView() {} + +void PlayView::beginUpdate() { GameView::beginUpdate(); } + +void PlayView::update() { GameView::update(); } + +void PlayView::commitUpdate() { GameView::commitUpdate(); } + +void PlayView::prepareRender() { GameView::prepareRender(); } + +void PlayView::render() { GameView::render(); } + +void PlayView::keyCallback(KeyCode code, InputAction action, KeyModifier modifier) { GameView::keyCallback(code, action, modifier); } diff --git a/src/Benchmark/PlayView.h b/src/Benchmark/PlayView.h new file mode 100644 index 0000000..08f3acd --- /dev/null +++ b/src/Benchmark/PlayView.h @@ -0,0 +1,22 @@ +#pragma once +#include "Window/GameView.h" + +namespace Seele { +class PlayView : public GameView { + public: + PlayView(Gfx::PGraphics graphics, PWindow window, const ViewportCreateInfo& createInfo, std::string dllPath, bool useMeshCulling); + virtual ~PlayView(); + virtual void beginUpdate() override; + virtual void update() override; + virtual void commitUpdate() override; + + virtual void prepareRender() override; + virtual void render() override; + + virtual void keyCallback(Seele::KeyCode code, Seele::InputAction action, Seele::KeyModifier modifier) override; + + private: + std::thread queryThread; +}; +DECLARE_REF(PlayView) +} // namespace Seele \ No newline at end of file diff --git a/src/Benchmark/main.cpp b/src/Benchmark/main.cpp new file mode 100644 index 0000000..75a71ec --- /dev/null +++ b/src/Benchmark/main.cpp @@ -0,0 +1,60 @@ +#include "Asset/AssetRegistry.h" +#include "Graphics/Initializer.h" +#include "Graphics/StaticMeshVertexData.h" +#include "Graphics/Vulkan/Graphics.h" +#include "PlayView.h" +#include "Window/WindowManager.h" +#include +#include + +using namespace Seele; + +// make it global so it gets deleted last and automatically +static Gfx::OGraphics graphics; + +int main(int argc, char** argv) { + if (argc > 2) + { + return -1; + } + bool useDepthCulling = true; + if (argc == 2 && strcmp(argv[1], "NOCULL") == 0) + { + useDepthCulling = false; + } + + std::filesystem::path binaryPath = "MeshShadingDemo.dll"; + graphics = new Vulkan::Graphics(); + GraphicsInitializer initializer; + graphics->init(initializer); + StaticMeshVertexData* vd = StaticMeshVertexData::getInstance(); + vd->init(graphics); + + OWindowManager windowManager = new WindowManager(); + AssetRegistry::init("Assets", graphics); + vd->commitMeshes(); + WindowCreateInfo mainWindowInfo = { + .width = 1920, + .height = 1080, + .title = "Benchmark", + .preferredFormat = Gfx::SE_FORMAT_B8G8R8A8_SRGB, + }; + auto window = windowManager->addWindow(graphics, mainWindowInfo); + ViewportCreateInfo sceneViewInfo = { + .dimensions = + { + .size = {1920, 1080}, + .offset = {0, 0}, + }, + .numSamples = Gfx::SE_SAMPLE_COUNT_4_BIT, + }; + OGameView sceneView = new PlayView(graphics, window, sceneViewInfo, binaryPath.generic_string(), useDepthCulling); + sceneView->setFocused(); + + while (windowManager->isActive()) { + windowManager->render(); + } + vd->destroy(); + + return 0; +} diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 7d3df86..0a63392 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,3 +1,4 @@ add_subdirectory(AssetViewer/) +add_subdirectory(Benchmark/) add_subdirectory(Editor/) add_subdirectory(Engine/) \ No newline at end of file diff --git a/src/Editor/Asset/TextureLoader.cpp b/src/Editor/Asset/TextureLoader.cpp index 6ceca0c..27a2fbf 100644 --- a/src/Editor/Asset/TextureLoader.cpp +++ b/src/Editor/Asset/TextureLoader.cpp @@ -56,119 +56,104 @@ PTextureAsset TextureLoader::getPlaceholderTexture() { return placeholderAsset; } void TextureLoader::import(TextureImportArgs args, PTextureAsset textureAsset) { - // manually transcode ktx textures using toktx - if (args.filePath.extension().compare("ktx") != 0) { - auto ktxFile = args.filePath; - ktxFile.replace_extension("ktx"); - std::stringstream ss; - ss << "toktx --encode etc1s "; - if (args.type == TextureImportType::TEXTURE_NORMAL) { - // ss << "--normal_mode "; - } - if (args.type == TextureImportType::TEXTURE_CUBEMAP) { - - } - ss << ktxFile << " " << args.filePath; - system(ss.str().c_str()); - args.filePath = ktxFile; + int totalWidth = 0, totalHeight = 0, n = 0; + unsigned char* data = stbi_load(args.filePath.string().c_str(), &totalWidth, &totalHeight, &n, 0); + ktxTexture2* kTexture = nullptr; + VkFormat format; + switch (n) { + case 1: + format = VK_FORMAT_R8_UNORM; + break; + case 2: + format = VK_FORMAT_R8G8_UNORM; + break; + case 3: + format = VK_FORMAT_R8G8B8_UNORM; + break; + case 4: + format = VK_FORMAT_R8G8B8A8_UNORM; + break; } + ktxTextureCreateInfo createInfo = { + .vkFormat = (uint32)format, + .baseDepth = 1, + .numLevels = 1, + .numLayers = 1, + .isArray = false, + .generateMipmaps = false, + }; - ktxTexture2* ktxHandle; - KTX_ASSERT(ktxTexture_CreateFromNamedFile(args.filePath.string().c_str(), 0, (ktxTexture**)&ktxHandle)); + if (args.type == TextureImportType::TEXTURE_CUBEMAP) { + uint32 faceWidth = totalWidth / 4; + // uint32 faceHeight = totalHeight / 3; + // Cube map + createInfo.baseWidth = totalWidth / 4; + createInfo.baseHeight = totalHeight / 3; + createInfo.numFaces = 6; + createInfo.numDimensions = 2; - // int totalWidth = 0, totalHeight = 0, n = 0; - // unsigned char* data = stbi_load(args.filePath.string().c_str(), &totalWidth, &totalHeight, &n, 4); - // ktxTexture2* kTexture = nullptr; - // VkFormat format = VK_FORMAT_R8G8B8A8_UNORM; - // ktxTextureCreateInfo createInfo = { - // .vkFormat = (uint32)format, - // .baseDepth = 1, - // .numLevels = 1, - // .numLayers = 1, - // .isArray = false, - // .generateMipmaps = false, - // }; - // - // if (args.type == TextureImportType::TEXTURE_CUBEMAP) - //{ - // uint32 faceWidth = totalWidth / 4; - // // uint32 faceHeight = totalHeight / 3; - // // Cube map - // createInfo.baseWidth = totalWidth / 4; - // createInfo.baseHeight = totalHeight / 3; - // createInfo.numFaces = 6; - // createInfo.numDimensions = 2; + KTX_ASSERT(ktxTexture2_Create(&createInfo, KTX_TEXTURE_CREATE_ALLOC_STORAGE, &kTexture)); - // KTX_ASSERT(ktxTexture2_Create(&createInfo, - // KTX_TEXTURE_CREATE_ALLOC_STORAGE, - // &kTexture)); + auto loadCubeFace = [n, &kTexture, faceWidth, totalWidth, &data](int xPos, int yPos, int faceName) { + std::vector vec(faceWidth * faceWidth * n); + for (uint32 y = 0; y < faceWidth; ++y) { + for (uint32 x = 0; x < faceWidth; ++x) { + int imgX = x + (xPos * faceWidth); + int imgY = y + (yPos * faceWidth); + std::memcpy(&vec[(x + (faceWidth * y)) * n], &data[(imgX + (totalWidth * imgY)) * n], n); + } + } + ktxTexture_SetImageFromMemory(ktxTexture(kTexture), 0, 0, faceName, vec.data(), vec.size()); + }; + loadCubeFace(2, 1, 0); // +X + loadCubeFace(0, 1, 1); // -X + loadCubeFace(1, 0, 2); // +Y + loadCubeFace(1, 2, 3); // -Y + loadCubeFace(1, 1, 4); // +Z + loadCubeFace(3, 1, 5); // -Z + } else { + createInfo.baseWidth = totalWidth; + createInfo.baseHeight = totalHeight; + createInfo.numFaces = 1; + createInfo.numDimensions = 1 + (totalHeight > 1); - // auto loadCubeFace = [&kTexture, &faceWidth, &totalWidth, &data](int xPos, int yPos, int faceName) - // { - // std::vector vec(faceWidth * faceWidth * 4); - // for (uint32 y = 0; y < faceWidth; ++y) - // { - // for (uint32 x = 0; x < faceWidth; ++x) - // { - // int imgX = x + (xPos * faceWidth); - // int imgY = y + (yPos * faceWidth); - // std::memcpy(&vec[(x + (faceWidth * y)) * 4], &data[(imgX + (totalWidth * imgY)) * 4], 4); - // } - // } - // ktxTexture_SetImageFromMemory(ktxTexture(kTexture), - // 0, 0, faceName, vec.data(), vec.size()); - // }; - // loadCubeFace(2, 1, 0); // +X - // loadCubeFace(0, 1, 1); // -X - // loadCubeFace(1, 0, 2); // +Y - // loadCubeFace(1, 2, 3); // -Y - // loadCubeFace(1, 1, 4); // +Z - // loadCubeFace(3, 1, 5); // -Z - //} - // else - //{ - // createInfo.baseWidth = totalWidth; - // createInfo.baseHeight = totalHeight; - // createInfo.numFaces = 1; - // createInfo.numDimensions = 1 + (totalHeight > 1); + ktxTexture2_Create(&createInfo, KTX_TEXTURE_CREATE_ALLOC_STORAGE, &kTexture); - // ktxTexture2_Create(&createInfo, - // KTX_TEXTURE_CREATE_ALLOC_STORAGE, - // &kTexture); + ktxTexture_SetImageFromMemory(ktxTexture(kTexture), 0, 0, 0, data, totalWidth * totalHeight * n * sizeof(unsigned char)); + } + ktxBasisParams basisParams = { + .structSize = sizeof(ktxBasisParams), + .uastc = true, + .threadCount = std::thread::hardware_concurrency() - 2, + .uastcFlags = KTX_PACK_UASTC_LEVEL_SLOWER, + .uastcRDO = true, + }; + KTX_ASSERT(ktxTexture2_CompressBasisEx(kTexture, &basisParams)); - // ktxTexture_SetImageFromMemory(ktxTexture(kTexture), - // 0, 0, 0, data, totalWidth * totalHeight * n * sizeof(unsigned char)); - //} - // ktxTexture_WriteToNamedFile(ktxTexture(kTexture), args.filePath.replace_extension(".ktx").string().c_str()); + KTX_ASSERT(ktxTexture2_DeflateZstd(kTexture, 20)); - // ktxBasisParams basisParams = { - // .structSize = sizeof(ktxBasisParams), - // .uastc = true, - // .threadCount = std::thread::hardware_concurrency(), - // .normalMap = normalMap, - // .uastcFlags = KTX_PACK_UASTC_LEVEL_VERYSLOW, - // .uastcRDO = true, - // .uastcRDOQualityScalar = 1, - // }; - // KTX_ASSERT(ktxTexture2_CompressBasisEx(kTexture, &basisParams)); - // KTX_ASSERT(ktxTexture2_DeflateZstd(kTexture, 3)); + char writer[100]; + snprintf(writer, sizeof(writer), "%s version %s", "SeeleEngine", "0.0.1"); + ktxHashList_AddKVPair(&kTexture->kvDataHead, KTX_WRITER_KEY, (ktx_uint32_t)strlen(writer) + 1, writer); - // char writer[100]; - // snprintf(writer, sizeof(writer), "%s version %s", "SeeleEngine", "0.0.1"); - // ktxHashList_AddKVPair(&kTexture->kvDataHead, KTX_WRITER_KEY, - // (ktx_uint32_t)strlen(writer) + 1, - // writer); + uint8* texData; + size_t texSize; + KTX_ASSERT(ktxTexture_WriteToMemory(ktxTexture(kTexture), &texData, &texSize)); - // uint8* texData; - // size_t texSize; - // KTX_ASSERT(ktxTexture_WriteToMemory(ktxTexture(kTexture), &texData, &texSize)); - // - // stbi_image_free(data); + ktxTexture_WriteToNamedFile(ktxTexture(kTexture), args.filePath.filename().replace_extension(".ktx").generic_string().c_str()); + + Array serialized(texSize); + std::memcpy(serialized.data(), texData, texSize); + + stbi_image_free(data); + ktxTexture_Destroy(ktxTexture(kTexture)); if (textureAsset->getName().empty()) { return; } + textureAsset->setTexture(std::move(serialized)); + std::string path = (std::filesystem::path(args.importPath) / textureAsset->getName()).string().append(".asset"); auto assetStream = AssetRegistry::createWriteStream(std::move(path), std::ios::binary); ArchiveBuffer buffer(graphics); @@ -179,7 +164,7 @@ void TextureLoader::import(TextureImportArgs args, PTextureAsset textureAsset) { // write folder Serialization::save(buffer, textureAsset->getFolderPath()); // write asset data - Serialization::save(buffer, args.filePath.string()); + textureAsset->save(buffer); buffer.writeToStream(assetStream); diff --git a/src/Editor/Window/PlayView.cpp b/src/Editor/Window/PlayView.cpp index 12bff3d..600451d 100644 --- a/src/Editor/Window/PlayView.cpp +++ b/src/Editor/Window/PlayView.cpp @@ -18,3 +18,31 @@ void PlayView::commitUpdate() { GameView::commitUpdate(); } void PlayView::prepareRender() { GameView::prepareRender(); } void PlayView::render() { GameView::render(); } + +void PlayView::keyCallback(KeyCode code, InputAction action, KeyModifier modifier) { + GameView::keyCallback(code, action, modifier); + if (code == KeyCode::KEY_P && action == InputAction::RELEASE) { + getGlobals().usePositionOnly = !getGlobals().usePositionOnly; + std::cout << "Use Pos only " << getGlobals().usePositionOnly << std::endl; + } + if (code == KeyCode::KEY_O && action == InputAction::RELEASE) { + getGlobals().useDepthCulling = !getGlobals().useDepthCulling; + std::cout << "Use Depth Culling " << getGlobals().useDepthCulling << std::endl; + } + if (code == KeyCode::KEY_L && action == InputAction::RELEASE) { + getGlobals().useLightCulling = !getGlobals().useLightCulling; + std::cout << "Use Light Culling " << getGlobals().useLightCulling << std::endl; + } + if (code == KeyCode::KEY_G && action == InputAction::RELEASE) { + Component::Camera cam; + Component::Transform tra; + scene->view([&cam, &tra](Component::Camera& c, Component::Transform& t) { + if (c.mainCamera) { + tra = t; + cam = c; + } + }); + std::cout << cam.getCameraPosition() << std::endl; + std::cout << tra.getRotation() << std::endl; + } +} diff --git a/src/Editor/Window/PlayView.h b/src/Editor/Window/PlayView.h index 82ed110..f236117 100644 --- a/src/Editor/Window/PlayView.h +++ b/src/Editor/Window/PlayView.h @@ -13,6 +13,8 @@ class PlayView : public GameView { virtual void prepareRender() override; virtual void render() override; + + virtual void keyCallback(Seele::KeyCode code, Seele::InputAction action, Seele::KeyModifier modifier) override; private: }; diff --git a/src/Editor/main.cpp b/src/Editor/main.cpp index 00eb234..8c58bdb 100644 --- a/src/Editor/main.cpp +++ b/src/Editor/main.cpp @@ -39,70 +39,72 @@ int main() { std::filesystem::path binaryPath = sourcePath / "cmake" / "libMeshShadingDemo.so"; #endif std::filesystem::path cmakePath = outputPath / "cmake"; - + if (true) { #ifdef __APPLE__ - graphics = new Metal::Graphics(); + graphics = new Metal::Graphics(); #else - graphics = new Vulkan::Graphics(); + graphics = new Vulkan::Graphics(); #endif - GraphicsInitializer initializer; - graphics->init(initializer); - StaticMeshVertexData* vd = StaticMeshVertexData::getInstance(); - vd->init(graphics); + GraphicsInitializer initializer; + graphics->init(initializer); + StaticMeshVertexData* vd = StaticMeshVertexData::getInstance(); + vd->init(graphics); - OWindowManager windowManager = new WindowManager(); - AssetRegistry::init(sourcePath / "Assets", graphics); - AssetImporter::init(graphics); - AssetImporter::importFont(FontImportArgs{ - .filePath = "./fonts/Calibri.ttf", - }); - AssetImporter::importMesh(MeshImportArgs{ - .filePath = sourcePath / "import/models/cube.fbx", - }); - AssetImporter::importTexture(TextureImportArgs{ - .filePath = sourcePath / "import/textures/skyboxsun5deg_tn.jpg", - .type = TextureImportType::TEXTURE_CUBEMAP, - }); - AssetImporter::importMesh(MeshImportArgs{ - .filePath = sourcePath / "import/models/after-the-rain-vr-sound/source/Whitechapel.fbx", - .importPath = "Whitechapel", - }); - AssetImporter::importMesh(MeshImportArgs{ - .filePath = sourcePath / "import/models/city-suburbs/source/city-suburbs.obj", - .importPath = "suburbs", - }); - vd->commitMeshes(); - WindowCreateInfo mainWindowInfo = { - .width = 1920, - .height = 1080, - .title = "SeeleEngine", - .preferredFormat = Gfx::SE_FORMAT_B8G8R8A8_SRGB, - }; - auto window = windowManager->addWindow(graphics, mainWindowInfo); - ViewportCreateInfo sceneViewInfo = { - .dimensions = - { - .size = {1920, 1080}, - .offset = {0, 0}, - }, - .numSamples = Gfx::SE_SAMPLE_COUNT_1_BIT, - }; - OGameView sceneView = new Editor::PlayView(graphics, window, sceneViewInfo, binaryPath.generic_string()); - sceneView->setFocused(); + OWindowManager windowManager = new WindowManager(); + AssetRegistry::init(sourcePath / "Assets", graphics); + AssetImporter::init(graphics); + // AssetImporter::importFont(FontImportArgs{ + // .filePath = "./fonts/Calibri.ttf", + // }); + AssetImporter::importMesh(MeshImportArgs{ + .filePath = sourcePath / "import/models/cube.fbx", + }); + AssetImporter::importTexture(TextureImportArgs{ + .filePath = sourcePath / "import/textures/skyboxsun5deg_tn.jpg", + .type = TextureImportType::TEXTURE_CUBEMAP, + }); + AssetImporter::importMesh(MeshImportArgs{ + .filePath = sourcePath / "import/models/after-the-rain-vr-sound/source/Whitechapel.fbx", + .importPath = "Whitechapel", + }); + // AssetImporter::importMesh(MeshImportArgs{ + // .filePath = sourcePath / "import/models/city-suburbs/source/city-suburbs.obj", + // .importPath = "suburbs", + // }); + vd->commitMeshes(); + WindowCreateInfo mainWindowInfo = { + .width = 1920, + .height = 1080, + .title = "SeeleEngine", + .preferredFormat = Gfx::SE_FORMAT_B8G8R8A8_SRGB, + }; + auto window = windowManager->addWindow(graphics, mainWindowInfo); + ViewportCreateInfo sceneViewInfo = { + .dimensions = + { + .size = {1920, 1080}, + .offset = {0, 0}, + }, + .numSamples = Gfx::SE_SAMPLE_COUNT_4_BIT, + }; + OGameView sceneView = new Editor::PlayView(graphics, window, sceneViewInfo, binaryPath.generic_string()); + sceneView->setFocused(); - while (windowManager->isActive()) { - windowManager->render(); - } - vd->destroy(); - // export game - if (false) { + while (windowManager->isActive() && getGlobals().running) { + windowManager->render(); + } + vd->destroy(); + // export game + + } else { std::filesystem::create_directories(outputPath); - std::system(fmt::format("cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo -DGAME_TITLE=\"{}\" -DGAME_DESTINATION=\"{}\" " + std::system(fmt::format("cmake -DCMAKE_BUILD_TYPE=Release -DGAME_TITLE=\"{}\" -DGAME_DESTINATION=\"{}\" " "-DGAME_BINARY=\"{}\" -P ./cmake/ExportProject.cmake", gameName, outputPath.generic_string(), binaryPath.generic_string()) .c_str()); - std::system(fmt::format("cmake -S {} -B {}", cmakePath.generic_string(), cmakePath.generic_string()).c_str()); + std::system(fmt::format("cmake -S {} -B {}", cmakePath.generic_string(), outputPath.generic_string()).c_str()); std::system(fmt::format("cmake --build {}", cmakePath.generic_string()).c_str()); + std::filesystem::copy(binaryPath, outputPath, std::filesystem::copy_options::recursive); std::filesystem::copy(sourcePath / "Assets", outputPath / "Assets", std::filesystem::copy_options::recursive); std::filesystem::copy("shaders", outputPath / "shaders", std::filesystem::copy_options::recursive); std::filesystem::copy("textures", outputPath / "textures", std::filesystem::copy_options::recursive); @@ -110,7 +112,6 @@ int main() { std::filesystem::copy_file("assimp-vc143-mt.dll", outputPath / "assimp-vc143-mt.dll"); std::filesystem::copy_file("slang.dll", outputPath / "slang.dll"); std::filesystem::copy_file("slang-glslang.dll", outputPath / "slang-glslang.dll"); - std::filesystem::copy_file("slang-llvm.dll", outputPath / "slang-llvm.dll"); #endif } return 0; diff --git a/src/Engine/Asset/TextureAsset.cpp b/src/Engine/Asset/TextureAsset.cpp index 593b8dc..58b147d 100644 --- a/src/Engine/Asset/TextureAsset.cpp +++ b/src/Engine/Asset/TextureAsset.cpp @@ -5,7 +5,6 @@ #include "Window/WindowManager.h" #include "ktx.h" - using namespace Seele; #define KTX_ASSERT(x) \ @@ -24,35 +23,17 @@ TextureAsset::TextureAsset(std::string_view folderPath, std::string_view name) : TextureAsset::~TextureAsset() {} void TextureAsset::save(ArchiveBuffer& buffer) const { - // ktxBasisParams basisParams = { - // .structSize = sizeof(ktxBasisParams), - // .uastc = true, - // .threadCount = std::thread::hardware_concurrency(), - // .normalMap = normalMap, - // .uastcFlags = KTX_PACK_UASTC_LEVEL_VERYSLOW, - // .uastcRDO = true, - // .uastcRDOQualityScalar = 1, - // }; - // KTX_ASSERT(ktxTexture2_CompressBasisEx(ktxHandle, &basisParams)); - // KTX_ASSERT(ktxTexture2_DeflateZstd(ktxHandle, 20)); - // ktx_uint8_t* texData; - // ktx_size_t texSize; - // KTX_ASSERT(ktxTexture_WriteToMemory(ktxTexture(ktxHandle), &texData, &texSize)); - // - // Array rawData(texSize); - // std::memcpy(rawData.data(), texData, texSize); - // Serialization::save(buffer, rawData); - // free(texData); + Serialization::save(buffer, ktxData); } void TextureAsset::load(ArchiveBuffer& buffer) { - std::string ktxPath; - Serialization::load(buffer, ktxPath); ktxTexture2* ktxHandle; + Serialization::load(buffer, ktxData); + KTX_ASSERT( + ktxTexture_CreateFromMemory(ktxData.data(), ktxData.size(), KTX_TEXTURE_CREATE_LOAD_IMAGE_DATA_BIT, (ktxTexture**)&ktxHandle)); - KTX_ASSERT(ktxTexture_CreateFromNamedFile(ktxPath.c_str(), KTX_TEXTURE_CREATE_NO_FLAGS, (ktxTexture**)&ktxHandle)); - - KTX_ASSERT(ktxTexture2_TranscodeBasis(ktxHandle, KTX_TTF_BC7_RGBA, 0)); + ktxTexture2_TranscodeBasis(ktxHandle, KTX_TTF_RGBA32, 0); + //ktxTexture2_DeflateZstd(ktxHandle, 0); Gfx::PGraphics graphics = buffer.getGraphics(); TextureCreateInfo createInfo = { @@ -60,7 +41,7 @@ void TextureAsset::load(ArchiveBuffer& buffer) { { .size = ktxTexture_GetDataSize(ktxTexture(ktxHandle)), .data = ktxTexture_GetData(ktxTexture(ktxHandle)), - .owner = Gfx::QueueType::TRANSFER, + .owner = Gfx::QueueType::GRAPHICS, }, .format = (Gfx::SeFormat)ktxHandle->vkFormat, .width = ktxHandle->baseWidth, @@ -79,12 +60,9 @@ void TextureAsset::load(ArchiveBuffer& buffer) { texture = graphics->createTexture2D(createInfo); } - texture->transferOwnership(Gfx::QueueType::GRAPHICS); ktxTexture_Destroy(ktxTexture(ktxHandle)); } -void TextureAsset::setTexture(Gfx::OTexture _texture) { texture = std::move(_texture); } - uint32 TextureAsset::getWidth() { return texture->getWidth(); } uint32 TextureAsset::getHeight() { return texture->getHeight(); } diff --git a/src/Engine/Asset/TextureAsset.h b/src/Engine/Asset/TextureAsset.h index 561ccc6..b42ccd3 100644 --- a/src/Engine/Asset/TextureAsset.h +++ b/src/Engine/Asset/TextureAsset.h @@ -12,14 +12,14 @@ class TextureAsset : public Asset { virtual ~TextureAsset(); virtual void save(ArchiveBuffer& buffer) const override; virtual void load(ArchiveBuffer& buffer) override; - void setTexture(Gfx::OTexture _texture); Gfx::PTexture getTexture() { return texture; } + void setTexture(Array data) { ktxData = std::move(data); } uint32 getWidth(); uint32 getHeight(); private: Gfx::OTexture texture; - bool normalMap; + Array ktxData; friend class TextureLoader; }; DEFINE_REF(TextureAsset) diff --git a/src/Engine/Graphics/Query.h b/src/Engine/Graphics/Query.h index 0bf7a97..0d394a0 100644 --- a/src/Engine/Graphics/Query.h +++ b/src/Engine/Graphics/Query.h @@ -51,7 +51,7 @@ class PipelineStatisticsQuery { DEFINE_REF(PipelineStatisticsQuery) struct Timestamp { std::string name; - std::chrono::nanoseconds time; + uint64 time; }; class TimestampQuery { public: diff --git a/src/Engine/Graphics/RenderPass/BasePass.cpp b/src/Engine/Graphics/RenderPass/BasePass.cpp index 5d19696..a869028 100644 --- a/src/Engine/Graphics/RenderPass/BasePass.cpp +++ b/src/Engine/Graphics/RenderPass/BasePass.cpp @@ -1,5 +1,6 @@ #include "BasePass.h" #include "Actor/CameraActor.h" +#include "Asset/AssetRegistry.h" #include "Component/Camera.h" #include "Component/Mesh.h" #include "Graphics/Command.h" @@ -7,6 +8,7 @@ #include "Graphics/Enums.h" #include "Graphics/Graphics.h" #include "Graphics/Initializer.h" +#include "Graphics/Pipeline.h" #include "Graphics/Shader.h" #include "Graphics/StaticMeshVertexData.h" #include "Material/MaterialInstance.h" @@ -16,6 +18,12 @@ using namespace Seele; +Array gDebugVertices; + +void Seele::addDebugVertex(DebugVertex vert) { gDebugVertices.add(vert); } + +void Seele::addDebugVertices(Array verts) { gDebugVertices.addAll(verts); } + BasePass::BasePass(Gfx::PGraphics graphics, PScene scene) : RenderPass(graphics, scene) { basePassLayout = graphics->createPipelineLayout("BasePassLayout"); @@ -68,6 +76,12 @@ BasePass::BasePass(Gfx::PGraphics graphics, PScene scene) : RenderPass(graphics, .useVisibility = false, }); } + skybox = Seele::Component::Skybox{ + .day = AssetRegistry::findTexture("", "skyboxsun5deg_tn")->getTexture().cast(), + .night = AssetRegistry::findTexture("", "skyboxsun5deg_tn")->getTexture().cast(), + .fogColor = Vector(0.1, 0.1, 0.8), + .blendFactor = 0, + }; } BasePass::~BasePass() {} @@ -81,6 +95,41 @@ void BasePass::beginFrame(const Component::Camera& cam) { lightCullingLayout->reset(); opaqueCulling = lightCullingLayout->allocateDescriptorSet(); transparentCulling = lightCullingLayout->allocateDescriptorSet(); + + // Debug vertices + VertexBufferCreateInfo vertexBufferInfo = { + .sourceData = + { + .size = sizeof(DebugVertex) * gDebugVertices.size(), + .data = (uint8*)gDebugVertices.data(), + }, + .vertexSize = sizeof(DebugVertex), + .numVertices = (uint32)gDebugVertices.size(), + .name = "DebugVertices", + }; + debugVertices = graphics->createVertexBuffer(vertexBufferInfo); + debugVertices->pipelineBarrier(Gfx::SE_ACCESS_TRANSFER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_TRANSFER_BIT, + Gfx::SE_ACCESS_VERTEX_ATTRIBUTE_READ_BIT, Gfx::SE_PIPELINE_STAGE_VERTEX_INPUT_BIT); + + // Skybox + skyboxDataLayout->reset(); + textureLayout->reset(); + skyboxData.transformMatrix = glm::rotate(skyboxData.transformMatrix, (float)(Gfx::getCurrentFrameDelta()), Vector(0, 1, 0)); + skyboxBuffer->rotateBuffer(sizeof(SkyboxData)); + skyboxBuffer->updateContents(DataSource{ + .size = sizeof(SkyboxData), + .data = (uint8*)&skyboxData, + }); + skyboxDataSet = skyboxDataLayout->allocateDescriptorSet(); + skyboxDataSet->updateBuffer(0, skyboxBuffer); + skyboxDataSet->writeChanges(); + skyboxBuffer->pipelineBarrier(Gfx::SE_ACCESS_TRANSFER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_TRANSFER_BIT, Gfx::SE_ACCESS_UNIFORM_READ_BIT, + Gfx::SE_PIPELINE_STAGE_FRAGMENT_SHADER_BIT); + textureSet = textureLayout->allocateDescriptorSet(); + textureSet->updateTexture(0, skybox.day); + textureSet->updateTexture(1, skybox.night); + textureSet->updateSampler(2, skyboxSampler); + textureSet->writeChanges(); } void BasePass::render() { @@ -95,7 +144,6 @@ void BasePass::render() { timestamps->write(Gfx::SE_PIPELINE_STAGE_TOP_OF_PIPE_BIT, "BASEPASS"); graphics->beginRenderPass(renderPass); Array commands; - Gfx::ShaderPermutation permutation = graphics->getShaderCompiler()->getTemplate("BasePass"); permutation.setDepthCulling(true); // always use the culling info permutation.setPositionOnly(false); @@ -193,110 +241,137 @@ void BasePass::render() { commands.add(std::move(command)); } } + graphics->executeCommands(std::move(commands)); - Map sortedDraws; - for (const auto& t : transparentData) { - Vector toCenter = Vector(t.worldPosition) - cameraPos; - float dist = glm::length(toCenter) * glm::dot(glm::normalize(toCenter), cameraForward); - sortedDraws[dist] = t; + commands.clear(); + // Transparent rendering + { + Map sortedDraws; + for (const auto& t : transparentData) { + Vector toCenter = Vector(t.worldPosition) - cameraPos; + float dist = glm::length(toCenter) * glm::dot(glm::normalize(toCenter), cameraForward); + sortedDraws[dist] = t; + } + Gfx::ORenderCommand transparentCommand = graphics->createRenderCommand("TransparentDraw"); + transparentCommand->setViewport(viewport); + for (const auto& [_, t] : sortedDraws) { + permutation.setVertexData(t.vertexData->getTypeName()); + permutation.setMaterial(t.matInst->getBaseMaterial()->getName()); + Gfx::PermutationId id(permutation); + + const Gfx::ShaderCollection* collection = graphics->getShaderCompiler()->findShaders(id); + assert(collection != nullptr); + + bool twoSided = t.matInst->getBaseMaterial()->isTwoSided(); + + if (graphics->supportMeshShading()) { + Gfx::MeshPipelineCreateInfo pipelineInfo = { + .taskShader = collection->taskShader, + .meshShader = collection->meshShader, + .fragmentShader = collection->fragmentShader, + .renderPass = renderPass, + .pipelineLayout = collection->pipelineLayout, + .multisampleState = + { + .samples = viewport->getSamples(), + }, + .rasterizationState = + { + .cullMode = Gfx::SeCullModeFlags(twoSided ? Gfx::SE_CULL_MODE_NONE : Gfx::SE_CULL_MODE_BACK_BIT), + }, + .depthStencilState = + { + .depthCompareOp = Gfx::SE_COMPARE_OP_GREATER_OR_EQUAL, + }, + .colorBlend = + { + .attachmentCount = 1, + .blendAttachments = + { + Gfx::ColorBlendState::BlendAttachment{ + .blendEnable = true, + }, + }, + }, + }; + Gfx::PGraphicsPipeline pipeline = graphics->createGraphicsPipeline(std::move(pipelineInfo)); + transparentCommand->bindPipeline(pipeline); + } else { + Gfx::LegacyPipelineCreateInfo pipelineInfo = { + .vertexShader = collection->vertexShader, + .fragmentShader = collection->fragmentShader, + .renderPass = renderPass, + .pipelineLayout = collection->pipelineLayout, + .multisampleState = + { + .samples = viewport->getSamples(), + }, + .rasterizationState = + { + .cullMode = Gfx::SeCullModeFlags(twoSided ? Gfx::SE_CULL_MODE_NONE : Gfx::SE_CULL_MODE_BACK_BIT), + }, + .depthStencilState = + { + .depthCompareOp = Gfx::SE_COMPARE_OP_GREATER_OR_EQUAL, + }, + .colorBlend = + { + .attachmentCount = 1, + .blendAttachments = + { + Gfx::ColorBlendState::BlendAttachment{ + .blendEnable = true, + }, + }, + }, + }; + Gfx::PGraphicsPipeline pipeline = graphics->createGraphicsPipeline(std::move(pipelineInfo)); + transparentCommand->bindPipeline(pipeline); + } + transparentCommand->bindDescriptor({viewParamsSet, t.vertexData->getVertexDataSet(), t.vertexData->getInstanceDataSet(), + scene->getLightEnvironment()->getDescriptorSet(), Material::getDescriptorSet(), + transparentCulling}); + transparentCommand->pushConstants(Gfx::SE_SHADER_STAGE_TASK_BIT_EXT | Gfx::SE_SHADER_STAGE_VERTEX_BIT | + Gfx::SE_SHADER_STAGE_FRAGMENT_BIT, + 0, sizeof(VertexData::DrawCallOffsets), &t.offsets); + if (graphics->supportMeshShading()) { + transparentCommand->drawMesh(1, 1, 1); + } else { + // command->bindIndexBuffer(t.vertexData->getIndexBuffer()); + // for (const auto& meshData : drawCall.instanceMeshData) { + // // all meshlets of a mesh share the same indices offset + // command->drawIndexed(meshData.numIndices, 1, meshData.firstIndex, + // vertexData->getIndicesOffset(meshData.meshletOffset), 0); + // } + } + } + commands.add(std::move(transparentCommand)); } - Gfx::ORenderCommand command = graphics->createRenderCommand("TransparentDraw"); - command->setViewport(viewport); - for (const auto& [_, t] : sortedDraws) { - permutation.setVertexData(t.vertexData->getTypeName()); - permutation.setMaterial(t.matInst->getBaseMaterial()->getName()); - Gfx::PermutationId id(permutation); - - const Gfx::ShaderCollection* collection = graphics->getShaderCompiler()->findShaders(id); - assert(collection != nullptr); - - bool twoSided = t.matInst->getBaseMaterial()->isTwoSided(); - - if (graphics->supportMeshShading()) { - Gfx::MeshPipelineCreateInfo pipelineInfo = { - .taskShader = collection->taskShader, - .meshShader = collection->meshShader, - .fragmentShader = collection->fragmentShader, - .renderPass = renderPass, - .pipelineLayout = collection->pipelineLayout, - .multisampleState = - { - .samples = viewport->getSamples(), - }, - .rasterizationState = - { - .cullMode = Gfx::SeCullModeFlags(twoSided ? Gfx::SE_CULL_MODE_NONE : Gfx::SE_CULL_MODE_BACK_BIT), - }, - .depthStencilState = - { - .depthCompareOp = Gfx::SE_COMPARE_OP_GREATER_OR_EQUAL, - }, - .colorBlend = - { - .attachmentCount = 1, - .blendAttachments = - { - Gfx::ColorBlendState::BlendAttachment{ - .blendEnable = true, - }, - }, - }, - }; - Gfx::PGraphicsPipeline pipeline = graphics->createGraphicsPipeline(std::move(pipelineInfo)); - command->bindPipeline(pipeline); - } else { - Gfx::LegacyPipelineCreateInfo pipelineInfo = { - .vertexShader = collection->vertexShader, - .fragmentShader = collection->fragmentShader, - .renderPass = renderPass, - .pipelineLayout = collection->pipelineLayout, - .multisampleState = - { - .samples = viewport->getSamples(), - }, - .rasterizationState = - { - .cullMode = Gfx::SeCullModeFlags(twoSided ? Gfx::SE_CULL_MODE_NONE : Gfx::SE_CULL_MODE_BACK_BIT), - }, - .depthStencilState = - { - .depthCompareOp = Gfx::SE_COMPARE_OP_GREATER_OR_EQUAL, - }, - .colorBlend = - { - .attachmentCount = 1, - .blendAttachments = - { - Gfx::ColorBlendState::BlendAttachment{ - .blendEnable = true, - }, - }, - }, - }; - Gfx::PGraphicsPipeline pipeline = graphics->createGraphicsPipeline(std::move(pipelineInfo)); - command->bindPipeline(pipeline); - } - command->bindDescriptor({viewParamsSet, t.vertexData->getVertexDataSet(), t.vertexData->getInstanceDataSet(), - scene->getLightEnvironment()->getDescriptorSet(), Material::getDescriptorSet(), transparentCulling}); - command->pushConstants(Gfx::SE_SHADER_STAGE_TASK_BIT_EXT | Gfx::SE_SHADER_STAGE_VERTEX_BIT | Gfx::SE_SHADER_STAGE_FRAGMENT_BIT, 0, - sizeof(VertexData::DrawCallOffsets), &t.offsets); - if (graphics->supportMeshShading()) { - command->drawMesh(1, 1, 1); - } else { - // command->bindIndexBuffer(t.vertexData->getIndexBuffer()); - // for (const auto& meshData : drawCall.instanceMeshData) { - // // all meshlets of a mesh share the same indices offset - // command->drawIndexed(meshData.numIndices, 1, meshData.firstIndex, vertexData->getIndicesOffset(meshData.meshletOffset), - // 0); - // } - } + // Debug vertices + if (gDebugVertices.size() > 0) { + Gfx::ORenderCommand debugCommand = graphics->createRenderCommand("DebugRender"); + debugCommand->setViewport(viewport); + debugCommand->bindPipeline(debugPipeline); + debugCommand->bindDescriptor(viewParamsSet); + debugCommand->bindVertexBuffer({debugVertices}); + debugCommand->draw((uint32)gDebugVertices.size(), 1, 0, 0); + commands.add(std::move(debugCommand)); } + Gfx::ORenderCommand skyboxCommand = graphics->createRenderCommand("SkyboxRender"); + skyboxCommand->setViewport(viewport); + skyboxCommand->bindPipeline(pipeline); + skyboxCommand->bindDescriptor({viewParamsSet, skyboxDataSet, textureSet}); + skyboxCommand->draw(36, 1, 0, 0); + + commands.add(std::move(skyboxCommand)); + graphics->executeCommands(std::move(commands)); graphics->endRenderPass(); query->endQuery(); timestamps->write(Gfx::SE_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, "END"); timestamps->end(); + gDebugVertices.clear(); } void BasePass::endFrame() {} @@ -306,17 +381,44 @@ void BasePass::publishOutputs() { .format = Gfx::SE_FORMAT_D32_SFLOAT, .width = viewport->getOwner()->getFramebufferWidth(), .height = viewport->getOwner()->getFramebufferHeight(), - .samples = viewport->getSamples(), .usage = Gfx::SE_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, }; basePassDepth = graphics->createTexture2D(depthBufferInfo); - colorAttachment = Gfx::RenderTargetAttachment(viewport, Gfx::SE_IMAGE_LAYOUT_UNDEFINED, Gfx::SE_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, - Gfx::SE_ATTACHMENT_LOAD_OP_CLEAR, Gfx::SE_ATTACHMENT_STORE_OP_STORE); - resources->registerRenderPassOutput("BASEPASS_COLOR", colorAttachment); + TextureCreateInfo msDepthInfo = { + .format = Gfx::SE_FORMAT_D32_SFLOAT, + .width = viewport->getOwner()->getFramebufferWidth(), + .height = viewport->getOwner()->getFramebufferHeight(), + .samples = viewport->getSamples(), + .usage = Gfx::SE_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | Gfx::SE_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT, + }; + msBasePassDepth = graphics->createTexture2D(msDepthInfo); + + TextureCreateInfo msBaseColorInfo = { + .format = viewport->getOwner()->getSwapchainFormat(), + .width = viewport->getOwner()->getFramebufferWidth(), + .height = viewport->getOwner()->getFramebufferHeight(), + .samples = viewport->getSamples(), + .usage = Gfx::SE_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | Gfx::SE_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT, + }; + msBasePassColor = graphics->createTexture2D(msBaseColorInfo); + depthAttachment = Gfx::RenderTargetAttachment(basePassDepth, Gfx::SE_IMAGE_LAYOUT_UNDEFINED, Gfx::SE_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, - Gfx::SE_ATTACHMENT_LOAD_OP_CLEAR, Gfx::SE_ATTACHMENT_STORE_OP_STORE); + Gfx::SE_ATTACHMENT_LOAD_OP_DONT_CARE, Gfx::SE_ATTACHMENT_STORE_OP_STORE); + + msDepthAttachment = + Gfx::RenderTargetAttachment(msBasePassDepth, Gfx::SE_IMAGE_LAYOUT_UNDEFINED, Gfx::SE_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, + Gfx::SE_ATTACHMENT_LOAD_OP_CLEAR, Gfx::SE_ATTACHMENT_STORE_OP_DONT_CARE); + + colorAttachment = Gfx::RenderTargetAttachment(viewport, Gfx::SE_IMAGE_LAYOUT_UNDEFINED, Gfx::SE_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, + Gfx::SE_ATTACHMENT_LOAD_OP_DONT_CARE, Gfx::SE_ATTACHMENT_STORE_OP_STORE); + + msColorAttachment = + Gfx::RenderTargetAttachment(msBasePassColor, Gfx::SE_IMAGE_LAYOUT_UNDEFINED, Gfx::SE_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, + Gfx::SE_ATTACHMENT_LOAD_OP_CLEAR, Gfx::SE_ATTACHMENT_STORE_OP_DONT_CARE); + + resources->registerRenderPassOutput("BASEPASS_COLOR", colorAttachment); resources->registerRenderPassOutput("BASEPASS_DEPTH", depthAttachment); query = graphics->createPipelineStatisticsQuery("BasePassPipelineStatistics"); @@ -328,15 +430,19 @@ void BasePass::createRenderPass() { cullingBuffer = resources->requestBuffer("CULLINGBUFFER"); Gfx::RenderTargetLayout layout = Gfx::RenderTargetLayout{ - .colorAttachments = {colorAttachment}, - .depthAttachment = depthAttachment, + .colorAttachments = {msColorAttachment}, + .resolveAttachments = {colorAttachment}, + .depthAttachment = msDepthAttachment, + .depthResolveAttachment = {depthAttachment}, }; Array dependency = { { .srcSubpass = ~0U, .dstSubpass = 0, - .srcStage = Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | Gfx::SE_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, - .dstStage = Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | Gfx::SE_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT, + .srcStage = Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | Gfx::SE_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | + Gfx::SE_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, + .dstStage = Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | Gfx::SE_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | + Gfx::SE_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, .srcAccess = Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, .dstAccess = Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | @@ -345,8 +451,10 @@ void BasePass::createRenderPass() { { .srcSubpass = 0, .dstSubpass = ~0U, - .srcStage = Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | Gfx::SE_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, - .dstStage = Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | Gfx::SE_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT, + .srcStage = Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | Gfx::SE_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | + Gfx::SE_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, + .dstStage = Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | Gfx::SE_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | + Gfx::SE_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, .srcAccess = Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, .dstAccess = Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | @@ -358,4 +466,151 @@ void BasePass::createRenderPass() { tLightIndexList = resources->requestBuffer("LIGHTCULLING_TLIGHTLIST"); oLightGrid = resources->requestTexture("LIGHTCULLING_OLIGHTGRID"); tLightGrid = resources->requestTexture("LIGHTCULLING_TLIGHTGRID"); + + // Debug rendering + { + debugPipelineLayout = graphics->createPipelineLayout("DebugPassLayout"); + debugPipelineLayout->addDescriptorLayout(viewParamsLayout); + + ShaderCreateInfo createInfo = { + .name = "DebugVertex", + .mainModule = "Debug", + .entryPoint = "vertexMain", + .rootSignature = debugPipelineLayout, + }; + debugVertexShader = graphics->createVertexShader(createInfo); + + createInfo.name = "DebugFragment"; + createInfo.entryPoint = "fragmentMain"; + debugFragmentShader = graphics->createFragmentShader(createInfo); + debugPipelineLayout->create(); + + VertexInputStateCreateInfo inputCreate = { + .bindings = + { + VertexInputBinding{ + .binding = 0, + .stride = sizeof(DebugVertex), + .inputRate = Gfx::SE_VERTEX_INPUT_RATE_VERTEX, + }, + }, + .attributes = + { + VertexInputAttribute{ + .location = 0, + .binding = 0, + .format = Gfx::SE_FORMAT_R32G32B32_SFLOAT, + .offset = 0, + }, + VertexInputAttribute{ + .location = 1, + .binding = 0, + .format = Gfx::SE_FORMAT_R32G32B32_SFLOAT, + .offset = sizeof(Vector), + }, + }, + }; + debugVertexInput = graphics->createVertexInput(inputCreate); + Gfx::LegacyPipelineCreateInfo gfxInfo = { + .topology = Gfx::SE_PRIMITIVE_TOPOLOGY_LINE_LIST, + .vertexInput = debugVertexInput, + .vertexShader = debugVertexShader, + .fragmentShader = debugFragmentShader, + .renderPass = renderPass, + .pipelineLayout = debugPipelineLayout, + .multisampleState = + { + .samples = viewport->getSamples(), + }, + .rasterizationState = + { + .polygonMode = Gfx::SE_POLYGON_MODE_LINE, + .lineWidth = 5.f, + }, + .colorBlend = + { + .attachmentCount = 1, + }, + }; + debugPipeline = graphics->createGraphicsPipeline(std::move(gfxInfo)); + } + + // Skybox + { + skyboxDataLayout = graphics->createDescriptorLayout("pSkyboxData"); + skyboxDataLayout->addDescriptorBinding(Gfx::DescriptorBinding{ + .binding = 0, + .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER, + }); + skyboxDataLayout->create(); + textureLayout = graphics->createDescriptorLayout("pSkyboxTextures"); + textureLayout->addDescriptorBinding(Gfx::DescriptorBinding{ + .binding = 0, + .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_SAMPLED_IMAGE, + }); + textureLayout->addDescriptorBinding(Gfx::DescriptorBinding{ + .binding = 1, + .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_SAMPLED_IMAGE, + }); + textureLayout->addDescriptorBinding(Gfx::DescriptorBinding{ + .binding = 2, + .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_SAMPLER, + }); + textureLayout->create(); + + skyboxSampler = graphics->createSampler({}); + + skyboxData.transformMatrix = Matrix4(1); + skyboxData.fogColor = skybox.fogColor; + skyboxData.blendFactor = skybox.blendFactor; + + skyboxBuffer = graphics->createUniformBuffer(UniformBufferCreateInfo{ + .sourceData = + { + .size = sizeof(SkyboxData), + .data = (uint8*)&skyboxData, + }, + .dynamic = true, + }); + + pipelineLayout = graphics->createPipelineLayout("SkyboxLayout"); + pipelineLayout->addDescriptorLayout(viewParamsLayout); + pipelineLayout->addDescriptorLayout(skyboxDataLayout); + pipelineLayout->addDescriptorLayout(textureLayout); + + ShaderCreateInfo createInfo = { + .name = "SkyboxVertex", + .mainModule = "Skybox", + .entryPoint = "vertexMain", + .rootSignature = pipelineLayout, + }; + vertexShader = graphics->createVertexShader(createInfo); + + createInfo.name = "SkyboxFragment"; + createInfo.entryPoint = "fragmentMain"; + fragmentShader = graphics->createFragmentShader(createInfo); + + pipelineLayout->create(); + + Gfx::LegacyPipelineCreateInfo gfxInfo = { + .topology = Gfx::SE_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, + .vertexShader = vertexShader, + .fragmentShader = fragmentShader, + .renderPass = renderPass, + .pipelineLayout = pipelineLayout, + .multisampleState = + { + .samples = viewport->getSamples(), + }, + .rasterizationState = + { + .polygonMode = Gfx::SE_POLYGON_MODE_FILL, + }, + .colorBlend = + { + .attachmentCount = 1, + }, + }; + pipeline = graphics->createGraphicsPipeline(std::move(gfxInfo)); + } } diff --git a/src/Engine/Graphics/RenderPass/BasePass.h b/src/Engine/Graphics/RenderPass/BasePass.h index 73c4e99..101b3f7 100644 --- a/src/Engine/Graphics/RenderPass/BasePass.h +++ b/src/Engine/Graphics/RenderPass/BasePass.h @@ -17,7 +17,9 @@ class BasePass : public RenderPass { virtual void createRenderPass() override; private: + Gfx::RenderTargetAttachment msColorAttachment; Gfx::RenderTargetAttachment colorAttachment; + Gfx::RenderTargetAttachment msDepthAttachment; Gfx::RenderTargetAttachment depthAttachment; Gfx::RenderTargetAttachment visibilityAttachment; Gfx::PShaderBuffer oLightIndexList; @@ -29,7 +31,9 @@ class BasePass : public RenderPass { Gfx::PDescriptorSet transparentCulling; // use a different texture here so we can do multisampling + Gfx::OTexture2D msBasePassDepth; Gfx::OTexture2D basePassDepth; + Gfx::OTexture2D msBasePassColor; // used for transparency sorting Vector cameraPos; @@ -43,6 +47,32 @@ class BasePass : public RenderPass { Gfx::PTimestampQuery timestamps; Gfx::PShaderBuffer cullingBuffer; + + // Debug rendering + Gfx::OVertexInput debugVertexInput; + Gfx::OVertexBuffer debugVertices; + Gfx::OVertexShader debugVertexShader; + Gfx::OFragmentShader debugFragmentShader; + Gfx::PGraphicsPipeline debugPipeline; + Gfx::OPipelineLayout debugPipelineLayout; + + // Skybox + Gfx::ODescriptorLayout skyboxDataLayout; + Gfx::PDescriptorSet skyboxDataSet; + Gfx::ODescriptorLayout textureLayout; + Gfx::PDescriptorSet textureSet; + Gfx::OVertexShader vertexShader; + Gfx::OFragmentShader fragmentShader; + Gfx::OPipelineLayout pipelineLayout; + Gfx::PGraphicsPipeline pipeline; + Gfx::OSampler skyboxSampler; + struct SkyboxData { + Matrix4 transformMatrix; + Vector fogColor; + float blendFactor; + } skyboxData; + Gfx::OUniformBuffer skyboxBuffer; + Component::Skybox skybox; }; DEFINE_REF(BasePass) } // namespace Seele diff --git a/src/Engine/Graphics/RenderPass/CMakeLists.txt b/src/Engine/Graphics/RenderPass/CMakeLists.txt index f5ff9d8..c7dc368 100644 --- a/src/Engine/Graphics/RenderPass/CMakeLists.txt +++ b/src/Engine/Graphics/RenderPass/CMakeLists.txt @@ -4,8 +4,6 @@ target_sources(Engine BasePass.cpp CachedDepthPass.h CachedDepthPass.cpp - DebugPass.h - DebugPass.cpp DepthCullingPass.h DepthCullingPass.cpp LightCullingPass.h @@ -17,8 +15,6 @@ target_sources(Engine RenderGraphResources.cpp RenderPass.h RenderPass.cpp - SkyboxRenderPass.h - SkyboxRenderPass.cpp TextPass.h TextPass.cpp UIPass.h @@ -31,14 +27,12 @@ target_sources(Engine FILES BasePass.h CachedDepthPass.h - DebugPass.h DepthCullingPass.h LightCullingPass.h RayTracingPass.h RenderGraph.h RenderGraphResources.h RenderPass.h - SkyboxRenderPass.h TextPass.h UIPass.h VisibilityPass.h) \ No newline at end of file diff --git a/src/Engine/Graphics/RenderPass/CachedDepthPass.cpp b/src/Engine/Graphics/RenderPass/CachedDepthPass.cpp index 057f40b..6fe28d4 100644 --- a/src/Engine/Graphics/RenderPass/CachedDepthPass.cpp +++ b/src/Engine/Graphics/RenderPass/CachedDepthPass.cpp @@ -3,9 +3,6 @@ using namespace Seele; -extern bool usePositionOnly; -extern bool useDepthCulling; - CachedDepthPass::CachedDepthPass(Gfx::PGraphics graphics, PScene scene) : RenderPass(graphics, scene) { depthPrepassLayout = graphics->createPipelineLayout("CachedDepthLayout"); depthPrepassLayout->addDescriptorLayout(viewParamsLayout); @@ -43,7 +40,9 @@ CachedDepthPass::CachedDepthPass(Gfx::PGraphics graphics, PScene scene) : Render CachedDepthPass::~CachedDepthPass() {} -void CachedDepthPass::beginFrame(const Component::Camera& cam) { RenderPass::beginFrame(cam); } +void CachedDepthPass::beginFrame(const Component::Camera& cam) { + RenderPass::beginFrame(cam); +} void CachedDepthPass::render() { query->beginQuery(); @@ -53,8 +52,8 @@ void CachedDepthPass::render() { Array commands; Gfx::ShaderPermutation permutation = graphics->getShaderCompiler()->getTemplate("CachedDepthPass"); - permutation.setPositionOnly(usePositionOnly); - permutation.setDepthCulling(useDepthCulling); + permutation.setPositionOnly(getGlobals().usePositionOnly); + permutation.setDepthCulling(getGlobals().useDepthCulling); for (VertexData* vertexData : VertexData::getList()) { permutation.setVertexData(vertexData->getTypeName()); vertexData->getInstanceDataSet()->updateBuffer(6, cullingBuffer); @@ -79,10 +78,6 @@ void CachedDepthPass::render() { .fragmentShader = collection->fragmentShader, .renderPass = renderPass, .pipelineLayout = collection->pipelineLayout, - .multisampleState = - { - .samples = viewport->getSamples(), - }, .colorBlend = { .attachmentCount = 1, @@ -96,10 +91,6 @@ void CachedDepthPass::render() { .fragmentShader = collection->fragmentShader, .renderPass = renderPass, .pipelineLayout = collection->pipelineLayout, - .multisampleState = - { - .samples = viewport->getSamples(), - }, .colorBlend = { .attachmentCount = 1, diff --git a/src/Engine/Graphics/RenderPass/DebugPass.cpp b/src/Engine/Graphics/RenderPass/DebugPass.cpp deleted file mode 100644 index a4cd74d..0000000 --- a/src/Engine/Graphics/RenderPass/DebugPass.cpp +++ /dev/null @@ -1,156 +0,0 @@ -#include "DebugPass.h" -#include "Graphics/Graphics.h" -#include "Graphics/Pipeline.h" -#include "Graphics/RenderTarget.h" -#include "Graphics/Shader.h" - - -using namespace Seele; - -Array gDebugVertices; - -void Seele::addDebugVertex(DebugVertex vert) { gDebugVertices.add(vert); } - -void Seele::addDebugVertices(Array verts) { gDebugVertices.addAll(verts); } - -DebugPass::DebugPass(Gfx::PGraphics graphics, PScene scene) : RenderPass(graphics, scene) {} - -DebugPass::~DebugPass() {} - -void DebugPass::beginFrame(const Component::Camera& cam) { - RenderPass::beginFrame(cam); - - VertexBufferCreateInfo vertexBufferInfo = { - .sourceData = - { - .size = sizeof(DebugVertex) * gDebugVertices.size(), - .data = (uint8*)gDebugVertices.data(), - }, - .vertexSize = sizeof(DebugVertex), - .numVertices = (uint32)gDebugVertices.size(), - .name = "DebugVertices", - }; - debugVertices = graphics->createVertexBuffer(vertexBufferInfo); -} - -void DebugPass::render() { - graphics->beginRenderPass(renderPass); - if (gDebugVertices.size() > 0) { - Gfx::ORenderCommand renderCommand = graphics->createRenderCommand("DebugRender"); - renderCommand->setViewport(viewport); - renderCommand->bindPipeline(pipeline); - renderCommand->bindDescriptor(viewParamsSet); - renderCommand->bindVertexBuffer({debugVertices}); - renderCommand->draw((uint32)gDebugVertices.size(), 1, 0, 0); - Array commands; - commands.add(std::move(renderCommand)); - graphics->executeCommands({std::move(commands)}); - } - graphics->endRenderPass(); - gDebugVertices.clear(); - // Sync color write with next pass/swapchain present - // colorAttachment.getTexture()->pipelineBarrier( - // Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, - // Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, - // Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, - // Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT - //); - // Sync depth with next pass/next frame - // depthAttachment.getTexture()->pipelineBarrier( - // Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, - // Gfx::SE_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, - // Gfx::SE_ACCESS_MEMORY_WRITE_BIT, - // Gfx::SE_PIPELINE_STAGE_TOP_OF_PIPE_BIT - //); -} - -void DebugPass::endFrame() {} - -void DebugPass::publishOutputs() {} - -void DebugPass::createRenderPass() { - colorAttachment = resources->requestRenderTarget("BASEPASS_COLOR"); - colorAttachment.setLoadOp(Gfx::SE_ATTACHMENT_LOAD_OP_LOAD); - colorAttachment.setInitialLayout(Gfx::SE_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); - colorAttachment.setInitialLayout(Gfx::SE_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); - - depthAttachment = resources->requestRenderTarget("BASEPASS_DEPTH"); - depthAttachment.setLoadOp(Gfx::SE_ATTACHMENT_LOAD_OP_LOAD); - depthAttachment.setInitialLayout(Gfx::SE_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL); - depthAttachment.setFinalLayout(Gfx::SE_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL); - Gfx::RenderTargetLayout layout = Gfx::RenderTargetLayout{ - .colorAttachments = {colorAttachment}, - .depthAttachment = depthAttachment, - }; - - Array dependency = { - { - .srcSubpass = ~0U, - .dstSubpass = 0, - .srcStage = Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | Gfx::SE_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, - .dstStage = Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | Gfx::SE_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT, - .srcAccess = Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | - Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, - .dstAccess = Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | - Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, - }, - { - .srcSubpass = 0, - .dstSubpass = ~0U, - .srcStage = Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | Gfx::SE_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, - .dstStage = Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | Gfx::SE_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT, - .srcAccess = Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | - Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, - .dstAccess = Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | - Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, - }, - }; - renderPass = graphics->createRenderPass(std::move(layout), dependency, viewport); - - pipelineLayout = graphics->createPipelineLayout("DebugPassLayout"); - pipelineLayout->addDescriptorLayout(viewParamsLayout); - - ShaderCreateInfo createInfo = { - .name = "DebugVertex", - .mainModule = "Debug", - .entryPoint = "vertexMain", - .rootSignature = pipelineLayout, - }; - vertexShader = graphics->createVertexShader(createInfo); - - createInfo.name = "DebugFragment"; - createInfo.entryPoint = "fragmentMain"; - fragmentShader = graphics->createFragmentShader(createInfo); - pipelineLayout->create(); - - VertexInputStateCreateInfo inputCreate = { - .bindings = - { - VertexInputBinding{ - .binding = 0, - .stride = sizeof(DebugVertex), - .inputRate = Gfx::SE_VERTEX_INPUT_RATE_VERTEX, - }, - }, - .attributes = {VertexInputAttribute{ - .location = 0, - .binding = 0, - .format = Gfx::SE_FORMAT_R32G32B32_SFLOAT, - .offset = 0, - }, - VertexInputAttribute{ - .location = 1, .binding = 0, .format = Gfx::SE_FORMAT_R32G32B32_SFLOAT, .offset = sizeof(Vector)}}, - }; - vertexInput = graphics->createVertexInput(inputCreate); - Gfx::LegacyPipelineCreateInfo gfxInfo; - gfxInfo.vertexInput = vertexInput; - gfxInfo.vertexShader = vertexShader; - gfxInfo.fragmentShader = fragmentShader; - gfxInfo.rasterizationState.polygonMode = Gfx::SE_POLYGON_MODE_LINE; - gfxInfo.topology = Gfx::SE_PRIMITIVE_TOPOLOGY_LINE_LIST; - gfxInfo.pipelineLayout = std::move(pipelineLayout); - gfxInfo.renderPass = renderPass; - gfxInfo.colorBlend.attachmentCount = 1; - gfxInfo.rasterizationState.lineWidth = 5.f; - pipeline = graphics->createGraphicsPipeline(std::move(gfxInfo)); -} diff --git a/src/Engine/Graphics/RenderPass/DebugPass.h b/src/Engine/Graphics/RenderPass/DebugPass.h deleted file mode 100644 index b69253f..0000000 --- a/src/Engine/Graphics/RenderPass/DebugPass.h +++ /dev/null @@ -1,35 +0,0 @@ -#pragma once -#include "Graphics/DebugVertex.h" -#include "Graphics/Pipeline.h" -#include "RenderPass.h" -#include "Scene/Scene.h" - - -namespace Seele { -DECLARE_REF(CameraActor) -DECLARE_REF(Scene) -DECLARE_REF(Viewport) -class DebugPass : public RenderPass { - public: - DebugPass(Gfx::PGraphics graphics, PScene scene); - DebugPass(DebugPass&&) = default; - DebugPass& operator=(DebugPass&&) = default; - virtual ~DebugPass(); - virtual void beginFrame(const Component::Camera& cam) override; - virtual void render() override; - virtual void endFrame() override; - virtual void publishOutputs() override; - virtual void createRenderPass() override; - - private: - Gfx::RenderTargetAttachment colorAttachment; - Gfx::RenderTargetAttachment depthAttachment; - Gfx::OVertexInput vertexInput; - Gfx::OVertexBuffer debugVertices; - Gfx::OVertexShader vertexShader; - Gfx::OFragmentShader fragmentShader; - Gfx::PGraphicsPipeline pipeline; - Gfx::OPipelineLayout pipelineLayout; -}; -DEFINE_REF(DebugPass) -} // namespace Seele diff --git a/src/Engine/Graphics/RenderPass/DepthCullingPass.cpp b/src/Engine/Graphics/RenderPass/DepthCullingPass.cpp index 714a71a..c724db4 100644 --- a/src/Engine/Graphics/RenderPass/DepthCullingPass.cpp +++ b/src/Engine/Graphics/RenderPass/DepthCullingPass.cpp @@ -4,9 +4,6 @@ using namespace Seele; -extern bool usePositionOnly; -extern bool useDepthCulling; - DepthCullingPass::DepthCullingPass(Gfx::PGraphics graphics, PScene scene) : RenderPass(graphics, scene) { depthAttachmentLayout = graphics->createDescriptorLayout("pDepthAttachment"); depthAttachmentLayout->addDescriptorBinding(Gfx::DescriptorBinding{ @@ -68,13 +65,15 @@ DepthCullingPass::DepthCullingPass(Gfx::PGraphics graphics, PScene scene) : Rend DepthCullingPass::~DepthCullingPass() {} -void DepthCullingPass::beginFrame(const Component::Camera& cam) { RenderPass::beginFrame(cam); } +void DepthCullingPass::beginFrame(const Component::Camera& cam) { + RenderPass::beginFrame(cam); +} void DepthCullingPass::render() { query->beginQuery(); depthAttachment.getTexture()->changeLayout(Gfx::SE_IMAGE_LAYOUT_GENERAL, Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, - Gfx::SE_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, Gfx::SE_ACCESS_TRANSFER_READ_BIT, - Gfx::SE_PIPELINE_STAGE_TRANSFER_BIT); + Gfx::SE_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, Gfx::SE_ACCESS_SHADER_READ_BIT, + Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT); Gfx::PDescriptorSet set = depthAttachmentLayout->allocateDescriptorSet(); set->updateTexture(0, Gfx::PTexture2D(depthAttachment.getTexture())); @@ -123,8 +122,8 @@ void DepthCullingPass::render() { Array commands; Gfx::ShaderPermutation permutation = graphics->getShaderCompiler()->getTemplate("DepthPass"); - permutation.setPositionOnly(usePositionOnly); - permutation.setDepthCulling(useDepthCulling); + permutation.setPositionOnly(getGlobals().usePositionOnly); + permutation.setDepthCulling(getGlobals().useDepthCulling); for (VertexData* vertexData : VertexData::getList()) { permutation.setVertexData(vertexData->getTypeName()); vertexData->getInstanceDataSet()->updateBuffer(6, cullingBuffer); @@ -148,10 +147,6 @@ void DepthCullingPass::render() { .fragmentShader = collection->fragmentShader, .renderPass = renderPass, .pipelineLayout = collection->pipelineLayout, - .multisampleState = - { - .samples = viewport->getSamples(), - }, .colorBlend = { .attachmentCount = 1, @@ -165,10 +160,6 @@ void DepthCullingPass::render() { .fragmentShader = collection->fragmentShader, .renderPass = renderPass, .pipelineLayout = collection->pipelineLayout, - .multisampleState = - { - .samples = viewport->getSamples(), - }, .colorBlend = { .attachmentCount = 1, diff --git a/src/Engine/Graphics/RenderPass/LightCullingPass.cpp b/src/Engine/Graphics/RenderPass/LightCullingPass.cpp index 6a30397..703b554 100644 --- a/src/Engine/Graphics/RenderPass/LightCullingPass.cpp +++ b/src/Engine/Graphics/RenderPass/LightCullingPass.cpp @@ -8,8 +8,6 @@ using namespace Seele; -extern bool useLightCulling; - LightCullingPass::LightCullingPass(Gfx::PGraphics graphics, PScene scene) : RenderPass(graphics, scene) {} LightCullingPass::~LightCullingPass() {} @@ -25,7 +23,13 @@ void LightCullingPass::beginFrame(const Component::Camera& cam) { Gfx::SE_PIPELINE_STAGE_TRANSFER_BIT); uint32 reset = 0; ShaderBufferCreateInfo counterReset = { - .sourceData = {.size = sizeof(uint32), .data = (uint8*)&reset, .owner = Gfx::QueueType::COMPUTE}}; + .sourceData = + { + .size = sizeof(uint32), + .data = (uint8*)&reset, + .owner = Gfx::QueueType::COMPUTE, + }, + }; oLightIndexCounter->rotateBuffer(sizeof(uint32)); oLightIndexCounter->updateContents(counterReset); tLightIndexCounter->rotateBuffer(sizeof(uint32)); @@ -42,7 +46,10 @@ void LightCullingPass::beginFrame(const Component::Camera& cam) { void LightCullingPass::render() { query->beginQuery(); timestamps->write(Gfx::SE_PIPELINE_STAGE_TOP_OF_PIPE_BIT, "LIGHTCULL"); - depthAttachment->transferOwnership(Gfx::QueueType::COMPUTE); + oLightGrid->pipelineBarrier(Gfx::SE_ACCESS_SHADER_READ_BIT, Gfx::SE_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, Gfx::SE_ACCESS_SHADER_WRITE_BIT, + Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT); + tLightGrid->pipelineBarrier(Gfx::SE_ACCESS_SHADER_READ_BIT, Gfx::SE_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, Gfx::SE_ACCESS_SHADER_WRITE_BIT, + Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT); cullingDescriptorSet->updateTexture(0, depthAttachment); cullingDescriptorSet->updateBuffer(1, oLightIndexCounter); cullingDescriptorSet->updateBuffer(2, tLightIndexCounter); @@ -52,7 +59,7 @@ void LightCullingPass::render() { cullingDescriptorSet->updateTexture(6, Gfx::PTexture2D(tLightGrid)); cullingDescriptorSet->writeChanges(); Gfx::OComputeCommand computeCommand = graphics->createComputeCommand("CullingCommand"); - if (useLightCulling) { + if (getGlobals().useLightCulling) { computeCommand->bindPipeline(cullingEnabledPipeline); } else { computeCommand->bindPipeline(cullingPipeline); @@ -84,11 +91,17 @@ void LightCullingPass::publishOutputs() { dispatchParams.numThreadGroups = numThreadGroups; dispatchParams.numThreads = numThreadGroups * glm::uvec3(BLOCK_SIZE, BLOCK_SIZE, 1); dispatchParamsBuffer = graphics->createUniformBuffer(UniformBufferCreateInfo{ - .sourceData = {.size = sizeof(DispatchParams), .data = (uint8*)&dispatchParams, .owner = Gfx::QueueType::COMPUTE}, + .sourceData = + { + .size = sizeof(DispatchParams), + .data = (uint8*)&dispatchParams, + .owner = Gfx::QueueType::COMPUTE, + }, .dynamic = false, .name = "DispatchParams", }); - + dispatchParamsBuffer->pipelineBarrier(Gfx::SE_ACCESS_TRANSFER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_TRANSFER_BIT, + Gfx::SE_ACCESS_UNIFORM_READ_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT); dispatchParamsSet = dispatchParamsLayout->allocateDescriptorSet(); dispatchParamsSet->updateBuffer(0, dispatchParamsBuffer); dispatchParamsSet->updateBuffer(1, frustumBuffer); @@ -209,6 +222,10 @@ void LightCullingPass::publishOutputs() { }; oLightGrid = graphics->createTexture2D(textureInfo); tLightGrid = graphics->createTexture2D(textureInfo); + oLightGrid->changeLayout(Gfx::SE_IMAGE_LAYOUT_GENERAL, Gfx::SE_ACCESS_NONE, Gfx::SE_PIPELINE_STAGE_TOP_OF_PIPE_BIT, + Gfx::SE_ACCESS_SHADER_READ_BIT | Gfx::SE_ACCESS_SHADER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT); + tLightGrid->changeLayout(Gfx::SE_IMAGE_LAYOUT_GENERAL, Gfx::SE_ACCESS_NONE, Gfx::SE_PIPELINE_STAGE_TOP_OF_PIPE_BIT, + Gfx::SE_ACCESS_SHADER_READ_BIT | Gfx::SE_ACCESS_SHADER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT); resources->registerTextureOutput("LIGHTCULLING_OLIGHTGRID", Gfx::PTexture2D(oLightGrid)); resources->registerTextureOutput("LIGHTCULLING_TLIGHTGRID", Gfx::PTexture2D(tLightGrid)); @@ -230,6 +247,8 @@ void LightCullingPass::setupFrustums() { glm::uvec3 numThreadGroups = glm::ceil(glm::vec3(numThreads.x / (float)BLOCK_SIZE, numThreads.y / (float)BLOCK_SIZE, 1)); RenderPass::beginFrame(Component::Camera()); + viewParamsBuffer->pipelineBarrier(Gfx::SE_ACCESS_TRANSFER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_TRANSFER_BIT, + Gfx::SE_ACCESS_UNIFORM_READ_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT); dispatchParams.numThreads = numThreads; dispatchParams.numThreadGroups = numThreadGroups; diff --git a/src/Engine/Graphics/RenderPass/LightCullingPass.h b/src/Engine/Graphics/RenderPass/LightCullingPass.h index 314e1ea..191c38f 100644 --- a/src/Engine/Graphics/RenderPass/LightCullingPass.h +++ b/src/Engine/Graphics/RenderPass/LightCullingPass.h @@ -41,7 +41,6 @@ class LightCullingPass : public RenderPass { Gfx::OShaderBuffer frustumBuffer; Gfx::OUniformBuffer dispatchParamsBuffer; - Gfx::OUniformBuffer viewParamsBuffer; Gfx::ODescriptorLayout dispatchParamsLayout; Gfx::PDescriptorSet dispatchParamsSet; Gfx::OComputeShader frustumShader; diff --git a/src/Engine/Graphics/RenderPass/RenderPass.cpp b/src/Engine/Graphics/RenderPass/RenderPass.cpp index e1a81f7..13366af 100644 --- a/src/Engine/Graphics/RenderPass/RenderPass.cpp +++ b/src/Engine/Graphics/RenderPass/RenderPass.cpp @@ -40,7 +40,9 @@ void RenderPass::beginFrame(const Component::Camera& cam) { viewParamsBuffer->rotateBuffer(sizeof(ViewParameter)); viewParamsBuffer->updateContents(uniformUpdate); viewParamsBuffer->pipelineBarrier(Gfx::SE_ACCESS_TRANSFER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_TRANSFER_BIT, - Gfx::SE_ACCESS_MEMORY_READ_BIT, Gfx::SE_PIPELINE_STAGE_ALL_COMMANDS_BIT); + Gfx::SE_ACCESS_UNIFORM_READ_BIT, + Gfx::SE_PIPELINE_STAGE_TASK_SHADER_BIT_EXT | Gfx::SE_PIPELINE_STAGE_MESH_SHADER_BIT_EXT | + Gfx::SE_PIPELINE_STAGE_VERTEX_SHADER_BIT | Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT); viewParamsLayout->reset(); viewParamsSet = viewParamsLayout->allocateDescriptorSet(); viewParamsSet->updateBuffer(0, viewParamsBuffer); diff --git a/src/Engine/Graphics/RenderPass/SkyboxRenderPass.cpp b/src/Engine/Graphics/RenderPass/SkyboxRenderPass.cpp deleted file mode 100644 index 24be324..0000000 --- a/src/Engine/Graphics/RenderPass/SkyboxRenderPass.cpp +++ /dev/null @@ -1,176 +0,0 @@ -#include "SkyboxRenderPass.h" -#include "Asset/AssetRegistry.h" -#include "Graphics/Command.h" -#include "Graphics/Graphics.h" - -using namespace Seele; - -SkyboxRenderPass::SkyboxRenderPass(Gfx::PGraphics graphics, PScene scene) : RenderPass(graphics, scene) { - skybox = Seele::Component::Skybox{ - .day = AssetRegistry::findTexture("", "skyboxsun5deg_tn")->getTexture().cast(), - .night = AssetRegistry::findTexture("", "skyboxsun5deg_tn")->getTexture().cast(), - .fogColor = Vector(0.1, 0.1, 0.8), - .blendFactor = 0, - }; -} -SkyboxRenderPass::~SkyboxRenderPass() {} - -void SkyboxRenderPass::beginFrame(const Component::Camera& cam) { - RenderPass::beginFrame(cam); - - skyboxDataLayout->reset(); - textureLayout->reset(); - skyboxData.transformMatrix = glm::rotate(skyboxData.transformMatrix, (float)(Gfx::getCurrentFrameDelta()), Vector(0, 1, 0)); - skyboxBuffer->updateContents(DataSource{ - .size = sizeof(SkyboxData), - .data = (uint8*)&skyboxData, - }); - skyboxDataSet = skyboxDataLayout->allocateDescriptorSet(); - skyboxDataSet->updateBuffer(0, skyboxBuffer); - skyboxDataSet->writeChanges(); - skyboxBuffer->pipelineBarrier(Gfx::SE_ACCESS_TRANSFER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_TRANSFER_BIT, Gfx::SE_ACCESS_MEMORY_READ_BIT, - Gfx::SE_PIPELINE_STAGE_VERTEX_SHADER_BIT); - textureSet = textureLayout->allocateDescriptorSet(); - textureSet->updateTexture(0, skybox.day); - textureSet->updateTexture(1, skybox.night); - textureSet->updateSampler(2, skyboxSampler); - textureSet->writeChanges(); -} - -void SkyboxRenderPass::render() { - colorAttachment.getTexture()->pipelineBarrier( - Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, - Gfx::SE_ACCESS_COLOR_ATTACHMENT_READ_BIT, Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT); - depthAttachment.getTexture()->pipelineBarrier( - Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, - Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT, Gfx::SE_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT); - graphics->beginRenderPass(renderPass); - Gfx::ORenderCommand renderCommand = graphics->createRenderCommand("SkyboxRender"); - renderCommand->setViewport(viewport); - renderCommand->bindPipeline(pipeline); - renderCommand->bindDescriptor({viewParamsSet, skyboxDataSet, textureSet}); - renderCommand->draw(36, 1, 0, 0); - Array commands; - commands.add(std::move(renderCommand)); - graphics->executeCommands(std::move(commands)); - graphics->endRenderPass(); -} - -void SkyboxRenderPass::endFrame() {} - -void SkyboxRenderPass::publishOutputs() { - skyboxDataLayout = graphics->createDescriptorLayout("pSkyboxData"); - skyboxDataLayout->addDescriptorBinding(Gfx::DescriptorBinding{ - .binding = 0, - .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER, - }); - skyboxDataLayout->create(); - textureLayout = graphics->createDescriptorLayout("pSkyboxTextures"); - textureLayout->addDescriptorBinding(Gfx::DescriptorBinding{ - .binding = 0, - .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_SAMPLED_IMAGE, - }); - textureLayout->addDescriptorBinding(Gfx::DescriptorBinding{ - .binding = 1, - .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_SAMPLED_IMAGE, - }); - textureLayout->addDescriptorBinding(Gfx::DescriptorBinding{ - .binding = 2, - .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_SAMPLER, - }); - textureLayout->create(); - - skyboxSampler = graphics->createSampler({}); -} - -void SkyboxRenderPass::createRenderPass() { - colorAttachment = resources->requestRenderTarget("BASEPASS_COLOR"); - colorAttachment.setLoadOp(Gfx::SE_ATTACHMENT_LOAD_OP_LOAD); - colorAttachment.setInitialLayout(Gfx::SE_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); - colorAttachment.setInitialLayout(Gfx::SE_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); - - depthAttachment = resources->requestRenderTarget("BASEPASS_DEPTH"); - depthAttachment.setLoadOp(Gfx::SE_ATTACHMENT_LOAD_OP_LOAD); - depthAttachment.setInitialLayout(Gfx::SE_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL); - depthAttachment.setFinalLayout(Gfx::SE_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL); - Gfx::RenderTargetLayout layout = Gfx::RenderTargetLayout{ - .colorAttachments = {colorAttachment}, - .depthAttachment = depthAttachment, - }; - Array dependency = { - { - .srcSubpass = ~0U, - .dstSubpass = 0, - .srcStage = Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | Gfx::SE_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, - .dstStage = Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | Gfx::SE_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT, - .srcAccess = Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | - Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, - .dstAccess = Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | - Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, - }, - { - .srcSubpass = 0, - .dstSubpass = ~0U, - .srcStage = Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | Gfx::SE_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, - .dstStage = Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | Gfx::SE_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT, - .srcAccess = Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | - Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, - .dstAccess = Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | - Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, - }, - }; - renderPass = graphics->createRenderPass(std::move(layout), dependency, viewport); - - skyboxData.transformMatrix = Matrix4(1); - skyboxData.fogColor = skybox.fogColor; - skyboxData.blendFactor = skybox.blendFactor; - - skyboxBuffer = graphics->createUniformBuffer(UniformBufferCreateInfo{ - .sourceData = - { - .size = sizeof(SkyboxData), - .data = (uint8*)&skyboxData, - }, - .dynamic = true, - }); - - pipelineLayout = graphics->createPipelineLayout("SkyboxLayout"); - pipelineLayout->addDescriptorLayout(viewParamsLayout); - pipelineLayout->addDescriptorLayout(skyboxDataLayout); - pipelineLayout->addDescriptorLayout(textureLayout); - - ShaderCreateInfo createInfo = { - .name = "SkyboxVertex", - .mainModule = "Skybox", - .entryPoint = "vertexMain", - .rootSignature = pipelineLayout, - }; - vertexShader = graphics->createVertexShader(createInfo); - - createInfo.name = "SkyboxFragment"; - createInfo.entryPoint = "fragmentMain"; - fragmentShader = graphics->createFragmentShader(createInfo); - - pipelineLayout->create(); - - Gfx::LegacyPipelineCreateInfo gfxInfo = { - .topology = Gfx::SE_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, - .vertexShader = vertexShader, - .fragmentShader = fragmentShader, - .renderPass = renderPass, - .pipelineLayout = pipelineLayout, - .multisampleState = - { - .samples = viewport->getSamples(), - }, - .rasterizationState = - { - .polygonMode = Gfx::SE_POLYGON_MODE_FILL, - }, - .colorBlend = - { - .attachmentCount = 1, - }, - }; - pipeline = graphics->createGraphicsPipeline(std::move(gfxInfo)); -} diff --git a/src/Engine/Graphics/RenderPass/SkyboxRenderPass.h b/src/Engine/Graphics/RenderPass/SkyboxRenderPass.h deleted file mode 100644 index 024c3b7..0000000 --- a/src/Engine/Graphics/RenderPass/SkyboxRenderPass.h +++ /dev/null @@ -1,41 +0,0 @@ -#pragma once -#include "Component/Skybox.h" -#include "Graphics/Shader.h" -#include "RenderPass.h" - - -namespace Seele { -class SkyboxRenderPass : public RenderPass { - public: - SkyboxRenderPass(Gfx::PGraphics graphics, PScene scene); - SkyboxRenderPass(SkyboxRenderPass&&) = default; - SkyboxRenderPass& operator=(SkyboxRenderPass&&) = default; - virtual ~SkyboxRenderPass(); - virtual void beginFrame(const Component::Camera& cam) override; - virtual void render() override; - virtual void endFrame() override; - virtual void publishOutputs() override; - virtual void createRenderPass() override; - - private: - Gfx::RenderTargetAttachment colorAttachment; - Gfx::RenderTargetAttachment depthAttachment; - Gfx::ODescriptorLayout skyboxDataLayout; - Gfx::PDescriptorSet skyboxDataSet; - Gfx::ODescriptorLayout textureLayout; - Gfx::PDescriptorSet textureSet; - Gfx::OVertexShader vertexShader; - Gfx::OFragmentShader fragmentShader; - Gfx::OPipelineLayout pipelineLayout; - Gfx::PGraphicsPipeline pipeline; - Gfx::OSampler skyboxSampler; - struct SkyboxData { - Matrix4 transformMatrix; - Vector fogColor; - float blendFactor; - } skyboxData; - Gfx::OUniformBuffer skyboxBuffer; - Component::Skybox skybox; -}; -DEFINE_REF(SkyboxRenderPass) -} // namespace Seele diff --git a/src/Engine/Graphics/RenderPass/VisibilityPass.cpp b/src/Engine/Graphics/RenderPass/VisibilityPass.cpp index 316992e..e7dc168 100644 --- a/src/Engine/Graphics/RenderPass/VisibilityPass.cpp +++ b/src/Engine/Graphics/RenderPass/VisibilityPass.cpp @@ -3,8 +3,6 @@ using namespace Seele; -extern bool resetVisibility; - VisibilityPass::VisibilityPass(Gfx::PGraphics graphics, PScene scene) : RenderPass(graphics, scene) {} VisibilityPass::~VisibilityPass() {} diff --git a/src/Engine/Graphics/Resources.h b/src/Engine/Graphics/Resources.h index 04e32de..050aedd 100644 --- a/src/Engine/Graphics/Resources.h +++ b/src/Engine/Graphics/Resources.h @@ -3,11 +3,6 @@ #include "Enums.h" #include "Math/Math.h" - -#ifndef ENABLE_VALIDATION -#define ENABLE_VALIDATION 1 -#endif - namespace Seele { DECLARE_REF(Material) namespace Gfx { diff --git a/src/Engine/Graphics/VertexData.cpp b/src/Engine/Graphics/VertexData.cpp index 39568b6..00f3d04 100644 --- a/src/Engine/Graphics/VertexData.cpp +++ b/src/Engine/Graphics/VertexData.cpp @@ -211,198 +211,195 @@ void VertexData::createDescriptors() { } void VertexData::loadMesh(MeshId id, Array loadedIndices, Array loadedMeshlets) { - std::unique_lock l(vertexDataLock); - meshlets.reserve(meshlets.size() + loadedMeshlets.size()); - vertexIndices.reserve(vertexIndices.size() + loadedMeshlets.size() * Gfx::numVerticesPerMeshlet); - primitiveIndices.reserve(primitiveIndices.size() + loadedMeshlets.size() * Gfx::numPrimitivesPerMeshlet * 3); - uint32 meshletOffset = meshlets.size(); - AABB meshAABB; - for (uint32 i = 0; i < loadedMeshlets.size(); ++i) { - Meshlet& m = loadedMeshlets[i]; - meshAABB = meshAABB.combine(m.boundingBox); - uint32 vertexOffset = vertexIndices.size(); - vertexIndices.resize(vertexOffset + m.numVertices); - std::memcpy(vertexIndices.data() + vertexOffset, m.uniqueVertices, m.numVertices * sizeof(uint32)); - uint32 primitiveOffset = primitiveIndices.size(); - primitiveIndices.resize(primitiveOffset + (m.numPrimitives * 3)); - std::memcpy(primitiveIndices.data() + primitiveOffset, m.primitiveLayout, m.numPrimitives * 3 * sizeof(uint8)); - meshlets.add(MeshletDescription{ - .bounding = m.boundingBox, //.toSphere(), - .vertexCount = m.numVertices, - .primitiveCount = m.numPrimitives, - .vertexOffset = vertexOffset, - .primitiveOffset = primitiveOffset, - .color = Vector((float)rand() / RAND_MAX, (float)rand() / RAND_MAX, (float)rand() / RAND_MAX), - .indicesOffset = (uint32)meshOffsets[id], - }); - } - meshData[id] = MeshData{ - .bounding = meshAABB, //.toSphere(), - .numMeshlets = (uint32)loadedMeshlets.size(), - .meshletOffset = meshletOffset, - .firstIndex = (uint32)indices.size(), - .numIndices = (uint32)loadedIndices.size(), - }; + std::unique_lock l(vertexDataLock); + meshlets.reserve(meshlets.size() + loadedMeshlets.size()); + vertexIndices.reserve(vertexIndices.size() + loadedMeshlets.size() * Gfx::numVerticesPerMeshlet); + primitiveIndices.reserve(primitiveIndices.size() + loadedMeshlets.size() * Gfx::numPrimitivesPerMeshlet * 3); + uint32 meshletOffset = meshlets.size(); + AABB meshAABB; + for (uint32 i = 0; i < loadedMeshlets.size(); ++i) { + Meshlet& m = loadedMeshlets[i]; + meshAABB = meshAABB.combine(m.boundingBox); + uint32 vertexOffset = vertexIndices.size(); + vertexIndices.resize(vertexOffset + m.numVertices); + std::memcpy(vertexIndices.data() + vertexOffset, m.uniqueVertices, m.numVertices * sizeof(uint32)); + uint32 primitiveOffset = primitiveIndices.size(); + primitiveIndices.resize(primitiveOffset + (m.numPrimitives * 3)); + std::memcpy(primitiveIndices.data() + primitiveOffset, m.primitiveLayout, m.numPrimitives * 3 * sizeof(uint8)); + meshlets.add(MeshletDescription{ + .bounding = m.boundingBox, //.toSphere(), + .vertexCount = m.numVertices, + .primitiveCount = m.numPrimitives, + .vertexOffset = vertexOffset, + .primitiveOffset = primitiveOffset, + .color = Vector((float)rand() / RAND_MAX, (float)rand() / RAND_MAX, (float)rand() / RAND_MAX), + .indicesOffset = (uint32)meshOffsets[id], + }); + } + meshData[id] = MeshData{ + .bounding = meshAABB, //.toSphere(), + .numMeshlets = (uint32)loadedMeshlets.size(), + .meshletOffset = meshletOffset, + .firstIndex = (uint32)indices.size(), + .numIndices = (uint32)loadedIndices.size(), + }; - indices.resize(indices.size() + loadedIndices.size()); - std::memcpy(indices.data() + meshData[id].firstIndex, loadedIndices.data(), loadedIndices.size() * sizeof(uint32)); + indices.resize(indices.size() + loadedIndices.size()); + std::memcpy(indices.data() + meshData[id].firstIndex, loadedIndices.data(), loadedIndices.size() * sizeof(uint32)); } void VertexData::commitMeshes() { - indexBuffer = graphics->createIndexBuffer(IndexBufferCreateInfo{ - .sourceData = - { - .size = sizeof(uint32) * indices.size(), - .data = (uint8*)indices.data(), - }, - .indexType = Gfx::SE_INDEX_TYPE_UINT32, - .name = "IndexBuffer", - }); - meshletBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{ - .sourceData = - { - .size = sizeof(MeshletDescription) * meshlets.size(), - .data = (uint8*)meshlets.data(), - }, - .numElements = meshlets.size(), - .dynamic = false, - .name = "MeshletBuffer", - }); - vertexIndicesBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{ - .sourceData = - { - .size = sizeof(uint32) * vertexIndices.size(), - .data = (uint8*)vertexIndices.data(), - }, - .numElements = vertexIndices.size(), - .dynamic = false, - .name = "VertexIndicesBuffer", - }); + indexBuffer = graphics->createIndexBuffer(IndexBufferCreateInfo{ + .sourceData = + { + .size = sizeof(uint32) * indices.size(), + .data = (uint8*)indices.data(), + }, + .indexType = Gfx::SE_INDEX_TYPE_UINT32, + .name = "IndexBuffer", + }); + meshletBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{ + .sourceData = + { + .size = sizeof(MeshletDescription) * meshlets.size(), + .data = (uint8*)meshlets.data(), + }, + .numElements = meshlets.size(), + .dynamic = false, + .name = "MeshletBuffer", + }); + vertexIndicesBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{ + .sourceData = + { + .size = sizeof(uint32) * vertexIndices.size(), + .data = (uint8*)vertexIndices.data(), + }, + .numElements = vertexIndices.size(), + .dynamic = false, + .name = "VertexIndicesBuffer", + }); - primitiveIndicesBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{ - .sourceData = - { - .size = sizeof(uint8) * primitiveIndices.size(), - .data = (uint8*)primitiveIndices.data(), - }, - .numElements = primitiveIndices.size(), - .dynamic = false, - .name = "PrimitiveIndicesBuffer", - }); + primitiveIndicesBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{ + .sourceData = + { + .size = sizeof(uint8) * primitiveIndices.size(), + .data = (uint8*)primitiveIndices.data(), + }, + .numElements = primitiveIndices.size(), + .dynamic = false, + .name = "PrimitiveIndicesBuffer", + }); } MeshId VertexData::allocateVertexData(uint64 numVertices) { - std::unique_lock l(vertexDataLock); - MeshId res{idCounter++}; - meshOffsets.add(head); - meshVertexCounts.add(numVertices); - meshData.add({}); - head += numVertices; - if (head > verticesAllocated) { - verticesAllocated = std::max(head, verticesAllocated + NUM_DEFAULT_ELEMENTS); - resizeBuffers(); - } - return res; + std::unique_lock l(vertexDataLock); + MeshId res{idCounter++}; + meshOffsets.add(head); + meshVertexCounts.add(numVertices); + meshData.add({}); + head += numVertices; + if (head > verticesAllocated) { + verticesAllocated = std::max(head, verticesAllocated + NUM_DEFAULT_ELEMENTS); + resizeBuffers(); + } + return res; } -uint64 VertexData::getMeshOffset(MeshId id) { - return meshOffsets[id]; } +uint64 VertexData::getMeshOffset(MeshId id) { return meshOffsets[id]; } -uint64 VertexData::getMeshVertexCount(MeshId id) { - return meshVertexCounts[id]; } +uint64 VertexData::getMeshVertexCount(MeshId id) { return meshVertexCounts[id]; } List vertexDataList; -List VertexData::getList() { - return vertexDataList; } +List VertexData::getList() { return vertexDataList; } VertexData* VertexData::findByTypeName(std::string name) { - for (auto vd : vertexDataList) { - if (vd->getTypeName() == name) { - return vd; - } + for (auto vd : vertexDataList) { + if (vd->getTypeName() == name) { + return vd; } - return nullptr; + } + return nullptr; } void VertexData::init(Gfx::PGraphics _graphics) { - graphics = _graphics; - verticesAllocated = NUM_DEFAULT_ELEMENTS; - instanceDataLayout = graphics->createDescriptorLayout("pScene"); + graphics = _graphics; + verticesAllocated = NUM_DEFAULT_ELEMENTS; + instanceDataLayout = graphics->createDescriptorLayout("pScene"); - // instanceData - instanceDataLayout->addDescriptorBinding(Gfx::DescriptorBinding{ - .binding = 0, - .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER, - }); - // meshData - instanceDataLayout->addDescriptorBinding(Gfx::DescriptorBinding{ - .binding = 1, - .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER, - }); - // meshletData - instanceDataLayout->addDescriptorBinding( - Gfx::DescriptorBinding{.binding = 2, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER}); - // primitiveIndices - instanceDataLayout->addDescriptorBinding( - Gfx::DescriptorBinding{.binding = 3, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER}); - // vertexIndices - instanceDataLayout->addDescriptorBinding( - Gfx::DescriptorBinding{.binding = 4, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER}); - // cullingOffset - instanceDataLayout->addDescriptorBinding( - Gfx::DescriptorBinding{.binding = 5, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER}); - // cullingInfos - instanceDataLayout->addDescriptorBinding( - Gfx::DescriptorBinding{.binding = 6, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER}); + // instanceData + instanceDataLayout->addDescriptorBinding(Gfx::DescriptorBinding{ + .binding = 0, + .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER, + }); + // meshData + instanceDataLayout->addDescriptorBinding(Gfx::DescriptorBinding{ + .binding = 1, + .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER, + }); + // meshletData + instanceDataLayout->addDescriptorBinding( + Gfx::DescriptorBinding{.binding = 2, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER}); + // primitiveIndices + instanceDataLayout->addDescriptorBinding( + Gfx::DescriptorBinding{.binding = 3, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER}); + // vertexIndices + instanceDataLayout->addDescriptorBinding( + Gfx::DescriptorBinding{.binding = 4, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER}); + // cullingOffset + instanceDataLayout->addDescriptorBinding( + Gfx::DescriptorBinding{.binding = 5, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER}); + // cullingInfos + instanceDataLayout->addDescriptorBinding( + Gfx::DescriptorBinding{.binding = 6, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER}); - instanceDataLayout->create(); + instanceDataLayout->create(); - cullingOffsetBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{ - .dynamic = true, - .name = "MeshletOffset", - }); - instanceBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{ - .dynamic = true, - .name = "InstanceBuffer", - }); - instanceMeshDataBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{ - .dynamic = true, - .name = "MeshDataBuffer", - }); + cullingOffsetBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{ + .dynamic = true, + .name = "MeshletOffset", + }); + instanceBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{ + .dynamic = true, + .name = "InstanceBuffer", + }); + instanceMeshDataBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{ + .dynamic = true, + .name = "MeshDataBuffer", + }); - transparentInstanceDataBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{ - .dynamic = true, - .name = "TransparentInstanceBuffer", - }); - transparentMeshDataBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{ - .dynamic = true, - .name = "TransparentMeshBuffer", - }); + transparentInstanceDataBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{ + .dynamic = true, + .name = "TransparentInstanceBuffer", + }); + transparentMeshDataBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{ + .dynamic = true, + .name = "TransparentMeshBuffer", + }); - resizeBuffers(); - graphics->getShaderCompiler()->registerVertexData(this); + resizeBuffers(); + graphics->getShaderCompiler()->registerVertexData(this); } void VertexData::destroy() { - instanceBuffer = nullptr; - instanceMeshDataBuffer = nullptr; - instanceDataLayout = nullptr; - meshletBuffer = nullptr; - vertexIndicesBuffer = nullptr; - primitiveIndicesBuffer = nullptr; - indexBuffer = nullptr; - meshData.clear(); - materialData.clear(); + instanceBuffer = nullptr; + instanceMeshDataBuffer = nullptr; + instanceDataLayout = nullptr; + meshletBuffer = nullptr; + vertexIndicesBuffer = nullptr; + primitiveIndicesBuffer = nullptr; + indexBuffer = nullptr; + meshData.clear(); + materialData.clear(); } VertexData::CullingMapping VertexData::getCullingMapping(entt::entity id, uint32 meshIndex, uint32 numMeshlets) { - MeshMapping key = MeshMapping{.id = id, .meshId = meshIndex}; - if (!instanceIdMap.contains(key)) { - instanceIdMap[key] = CullingMapping{.instanceId = instanceCount++, .cullingOffset = uint32(meshletCount)}; - meshletCount += numMeshlets; - } - return instanceIdMap[key]; + MeshMapping key = MeshMapping{.id = id, .meshId = meshIndex}; + if (!instanceIdMap.contains(key)) { + instanceIdMap[key] = CullingMapping{.instanceId = instanceCount++, .cullingOffset = uint32(meshletCount)}; + meshletCount += numMeshlets; + } + return instanceIdMap[key]; } VertexData::VertexData() : idCounter(0), head(0), verticesAllocated(0), dirty(false) {} diff --git a/src/Engine/Graphics/Vulkan/Buffer.cpp b/src/Engine/Graphics/Vulkan/Buffer.cpp index b5db025..54ca8ec 100644 --- a/src/Engine/Graphics/Vulkan/Buffer.cpp +++ b/src/Engine/Graphics/Vulkan/Buffer.cpp @@ -262,8 +262,20 @@ void Buffer::copyBuffer(uint64 src, uint64 dst) { .offset = 0, .size = buffers[src]->size, }; - vkCmdPipelineBarrier(command->getHandle(), VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 1, - &srcBarrier, 0, nullptr); + VkBufferMemoryBarrier clearBarrier = { + .sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, + .pNext = nullptr, + .srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT, + .dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT, + .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, + .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, + .buffer = buffers[dst]->buffer, + .offset = 0, + .size = buffers[dst]->size, + }; + VkBufferMemoryBarrier srcBarriers[] = {srcBarrier, clearBarrier}; + vkCmdPipelineBarrier(command->getHandle(), VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 2, + srcBarriers, 0, nullptr); VkBufferCopy region = { .srcOffset = 0, .dstOffset = 0, diff --git a/src/Engine/Graphics/Vulkan/Command.cpp b/src/Engine/Graphics/Vulkan/Command.cpp index ed70621..92731fe 100644 --- a/src/Engine/Graphics/Vulkan/Command.cpp +++ b/src/Engine/Graphics/Vulkan/Command.cpp @@ -141,7 +141,6 @@ void Command::checkFence() { } void Command::waitForCommand(uint32 timeout) { - pool->submitCommands(); if (state == State::Begin) { // is already done return; diff --git a/src/Engine/Graphics/Vulkan/Graphics.cpp b/src/Engine/Graphics/Vulkan/Graphics.cpp index 3d81124..08c3989 100644 --- a/src/Engine/Graphics/Vulkan/Graphics.cpp +++ b/src/Engine/Graphics/Vulkan/Graphics.cpp @@ -46,7 +46,10 @@ void vkCmdDrawMeshTasksIndirectEXT(VkCommandBuffer commandBuffer, VkBuffer buffe } VkResult vkSetDebugUtilsObjectNameEXT(VkDevice device, const VkDebugUtilsObjectNameInfoEXT* pNameInfo) { - return setDebugUtilsObjectName(device, pNameInfo); + if (setDebugUtilsObjectName != nullptr) { + return setDebugUtilsObjectName(device, pNameInfo); + } + return VK_SUCCESS; } VkResult vkCreateAccelerationStructureKHR(VkDevice device, const VkAccelerationStructureCreateInfoKHR* pCreateInfo, @@ -139,7 +142,9 @@ void Graphics::beginRenderPass(Gfx::PRenderPass renderPass) { getGraphicsCommands()->getCommands()->beginRenderPass(rp, framebuffer); } -void Graphics::endRenderPass() { getGraphicsCommands()->getCommands()->endRenderPass(); } +void Graphics::endRenderPass() { + getGraphicsCommands()->getCommands()->endRenderPass(); +} void Graphics::waitDeviceIdle() { vkDeviceWaitIdle(handle); } diff --git a/src/Engine/Graphics/Vulkan/Query.cpp b/src/Engine/Graphics/Vulkan/Query.cpp index f235139..3f31e83 100644 --- a/src/Engine/Graphics/Vulkan/Query.cpp +++ b/src/Engine/Graphics/Vulkan/Query.cpp @@ -150,14 +150,9 @@ Array TimestampQuery::getResults() { tail = (tail + 1) % 512; Array res; for (uint64 i = 0; i < numTimestamps; ++i) { - if (results[i] < lastMeasure) - { - wrapping += 1ull << graphics->getTimestampValidBits(); - } - lastMeasure = results[i]; res.add(Gfx::Timestamp{ .name = pendingTimestamps[firstQuery + i], - .time = std::chrono::nanoseconds(uint64((results[i] + wrapping) * graphics->getTimestampPeriod())), + .time = uint64((results[i] + wrapping) * graphics->getTimestampPeriod()), }); } return res; diff --git a/src/Engine/Graphics/Vulkan/RenderPass.cpp b/src/Engine/Graphics/Vulkan/RenderPass.cpp index 6cb45c8..175918a 100644 --- a/src/Engine/Graphics/Vulkan/RenderPass.cpp +++ b/src/Engine/Graphics/Vulkan/RenderPass.cpp @@ -79,7 +79,7 @@ RenderPass::RenderPass(PGraphics graphics, Gfx::RenderTargetLayout _layout, Arra .pNext = nullptr, .flags = 0, .format = cast(resolveAttachment.getFormat()), - .samples = (VkSampleCountFlagBits)resolveAttachment.getNumSamples(), + .samples = (VkSampleCountFlagBits)resolveAttachment.getTexture()->getNumSamples(), .loadOp = cast(resolveAttachment.getLoadOp()), .storeOp = cast(resolveAttachment.getStoreOp()), .stencilLoadOp = cast(resolveAttachment.getStencilLoadOp()), @@ -143,6 +143,10 @@ RenderPass::RenderPass(PGraphics graphics, Gfx::RenderTargetLayout _layout, Arra .initialLayout = cast(layout.depthResolveAttachment.getInitialLayout()), .finalLayout = cast(layout.depthResolveAttachment.getFinalLayout()), }; + VkClearValue& clearValue = clearValues.add(); + if (attachments.back().loadOp == VK_ATTACHMENT_LOAD_OP_CLEAR) { + clearValue = cast(layout.depthResolveAttachment.clear); + } depthResolveRef = { .sType = VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2, .pNext = nullptr, @@ -214,14 +218,22 @@ uint32 RenderPass::getFramebufferHash() { PTexture2D tex = colorAttachment.getTexture().cast(); description.colorAttachments[description.numColorAttachments++] = tex->getView(); } + for (auto& resolveAttachment : layout.resolveAttachments) { + PTexture2D tex = resolveAttachment.getTexture().cast(); + description.resolveAttachments[description.numResolveAttachments++] = tex->getView(); + } if (layout.depthAttachment.getTexture() != nullptr) { PTexture2D tex = layout.depthAttachment.getTexture().cast(); description.depthAttachment = tex->getView(); } + if (layout.depthResolveAttachment.getTexture() != nullptr) { + PTexture2D tex = layout.depthResolveAttachment.getTexture().cast(); + description.depthResolveAttachment = tex->getView(); + } return CRC::Calculate(&description, sizeof(FramebufferDescription), CRC::CRC_32()); } -void Vulkan::RenderPass::endRenderPass() { +void RenderPass::endRenderPass() { for (auto& inputAttachment : layout.inputAttachments) { PTexture2D tex = inputAttachment.getTexture().cast(); tex->setLayout(inputAttachment.getFinalLayout()); @@ -230,8 +242,16 @@ void Vulkan::RenderPass::endRenderPass() { PTexture2D tex = colorAttachment.getTexture().cast(); tex->setLayout(colorAttachment.getFinalLayout()); } + for (auto& resolveAttachment : layout.resolveAttachments) { + PTexture2D tex = resolveAttachment.getTexture().cast(); + tex->setLayout(resolveAttachment.getFinalLayout()); + } if (layout.depthAttachment.getTexture() != nullptr) { PTexture2D tex = layout.depthAttachment.getTexture().cast(); tex->setLayout(layout.depthAttachment.getFinalLayout()); } + if (layout.depthResolveAttachment.getTexture() != nullptr) { + PTexture2D tex = layout.depthResolveAttachment.getTexture().cast(); + tex->setLayout(layout.depthResolveAttachment.getFinalLayout()); + } } diff --git a/src/Engine/Graphics/Vulkan/Texture.cpp b/src/Engine/Graphics/Vulkan/Texture.cpp index e9e117d..e083371 100644 --- a/src/Engine/Graphics/Vulkan/Texture.cpp +++ b/src/Engine/Graphics/Vulkan/Texture.cpp @@ -137,17 +137,6 @@ TextureHandle::TextureHandle(PGraphics graphics, VkImageViewType viewType, const changeLayout(Gfx::SE_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_ACCESS_TRANSFER_WRITE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_ACCESS_SHADER_READ_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT); graphics->getDestructionManager()->queueResourceForDestruction(std::move(stagingAlloc)); - } else { - if (usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) { - changeLayout(Gfx::SE_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VK_ACCESS_NONE, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, - VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT); - } else if (usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) { - changeLayout(Gfx::SE_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_ACCESS_NONE, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, - VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT); - } else { - changeLayout(Gfx::SE_IMAGE_LAYOUT_GENERAL, VK_ACCESS_NONE, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, VK_ACCESS_MEMORY_WRITE_BIT, - VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT); - } } VkImageViewCreateInfo viewInfo = { .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, @@ -331,7 +320,7 @@ void TextureHandle::generateMipmaps() { .aspectMask = aspect, .levelCount = 1, .baseArrayLayer = 0, - .layerCount = 1, + .layerCount = layerCount, }, }; int32 mipWidth = width; diff --git a/src/Engine/Graphics/Vulkan/Window.cpp b/src/Engine/Graphics/Vulkan/Window.cpp index 28cbf7d..0cb161b 100644 --- a/src/Engine/Graphics/Vulkan/Window.cpp +++ b/src/Engine/Graphics/Vulkan/Window.cpp @@ -5,7 +5,6 @@ #include "Resources.h" #include - using namespace Seele; using namespace Seele::Vulkan; @@ -93,9 +92,9 @@ void Window::pollInput() { glfwPollEvents(); } void Window::beginFrame() { imageAvailableFences[currentSemaphoreIndex]->reset(); - vkAcquireNextImageKHR(graphics->getDevice(), swapchain, std::numeric_limits::max(), - imageAvailableSemaphores[currentSemaphoreIndex]->getHandle(), - imageAvailableFences[currentSemaphoreIndex]->getHandle(), ¤tImageIndex); + VK_CHECK(vkAcquireNextImageKHR(graphics->getDevice(), swapchain, std::numeric_limits::max(), + imageAvailableSemaphores[currentSemaphoreIndex]->getHandle(), + imageAvailableFences[currentSemaphoreIndex]->getHandle(), ¤tImageIndex)); imageAvailableFences[currentSemaphoreIndex]->submit(); graphics->getGraphicsCommands()->getCommands()->waitForSemaphore(VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, imageAvailableSemaphores[currentSemaphoreIndex]); diff --git a/src/Engine/Math/Vector.cpp b/src/Engine/Math/Vector.cpp index 63d30f4..3e198a9 100644 --- a/src/Engine/Math/Vector.cpp +++ b/src/Engine/Math/Vector.cpp @@ -26,15 +26,20 @@ void from_json(const nlohmann::json& j, Vector& vec) { } std::ostream& operator<<(std::ostream& stream, const Vector2& vector) { - stream << "(" << vector.x << ", " << vector.y << ")"; + stream << "Vec2(" << vector.x << ", " << vector.y << ")"; return stream; } std::ostream& operator<<(std::ostream& stream, const Vector& vector) { - stream << "(" << vector.x << ", " << vector.y << ", " << vector.z << ")"; + stream << "Vec3(" << vector.x << ", " << vector.y << ", " << vector.z << ")"; return stream; } std::ostream& operator<<(std::ostream& stream, const Vector4& vector) { - stream << "(" << vector.x << ", " << vector.y << ", " << vector.z << ", " << vector.w << ")"; + stream << "Vec4(" << vector.x << ", " << vector.y << ", " << vector.z << ", " << vector.w << ")"; + return stream; +} + +std::ostream& operator<<(std::ostream& stream, const Quaternion& vector) { + stream << "Quat(" << vector.w << ", " << vector.x << ", " << vector.y << ", " << vector.z << ")"; return stream; } diff --git a/src/Engine/Math/Vector.h b/src/Engine/Math/Vector.h index ca45b66..aa8d930 100644 --- a/src/Engine/Math/Vector.h +++ b/src/Engine/Math/Vector.h @@ -37,3 +37,4 @@ void from_json(nlohmann::json& j, Vector& vec); std::ostream& operator<<(std::ostream& stream, const Seele::Vector2& vector); std::ostream& operator<<(std::ostream& stream, const Seele::Vector& vector); std::ostream& operator<<(std::ostream& stream, const Seele::Vector4& vector); +std::ostream& operator<<(std::ostream& stream, const Seele::Quaternion& vector); diff --git a/src/Engine/MinimalEngine.h b/src/Engine/MinimalEngine.h index 08e70bf..42b8803 100644 --- a/src/Engine/MinimalEngine.h +++ b/src/Engine/MinimalEngine.h @@ -142,4 +142,13 @@ template class UniquePtr { private: T* handle; }; + +// idk if it should be here? +struct Globals { + bool usePositionOnly = true; + bool useDepthCulling = true; + bool useLightCulling = true; + bool running = true; +}; +Globals& getGlobals(); } // namespace Seele diff --git a/src/Engine/Scene/LightEnvironment.cpp b/src/Engine/Scene/LightEnvironment.cpp index ddf6bd4..66caebb 100644 --- a/src/Engine/Scene/LightEnvironment.cpp +++ b/src/Engine/Scene/LightEnvironment.cpp @@ -60,11 +60,14 @@ void LightEnvironment::addDirectionalLight(Component::DirectionalLight dirLight) void LightEnvironment::addPointLight(Component::PointLight pointLight) { points.add(pointLight); } void LightEnvironment::commit() { - lightEnvBuffer->pipelineBarrier(Gfx::SE_ACCESS_SHADER_READ_BIT, Gfx::SE_PIPELINE_STAGE_ALL_COMMANDS_BIT, + lightEnvBuffer->pipelineBarrier(Gfx::SE_ACCESS_UNIFORM_READ_BIT | Gfx::SE_ACCESS_TRANSFER_WRITE_BIT, + Gfx::SE_PIPELINE_STAGE_ALL_COMMANDS_BIT, Gfx::SE_ACCESS_TRANSFER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_TRANSFER_BIT); - pointLights->pipelineBarrier(Gfx::SE_ACCESS_SHADER_READ_BIT, Gfx::SE_PIPELINE_STAGE_ALL_COMMANDS_BIT, Gfx::SE_ACCESS_TRANSFER_WRITE_BIT, + pointLights->pipelineBarrier(Gfx::SE_ACCESS_SHADER_READ_BIT | Gfx::SE_ACCESS_TRANSFER_WRITE_BIT, + Gfx::SE_PIPELINE_STAGE_ALL_COMMANDS_BIT, Gfx::SE_ACCESS_TRANSFER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_TRANSFER_BIT); - directionalLights->pipelineBarrier(Gfx::SE_ACCESS_SHADER_READ_BIT, Gfx::SE_PIPELINE_STAGE_ALL_COMMANDS_BIT, + directionalLights->pipelineBarrier(Gfx::SE_ACCESS_SHADER_READ_BIT | Gfx::SE_ACCESS_TRANSFER_WRITE_BIT, + Gfx::SE_PIPELINE_STAGE_ALL_COMMANDS_BIT, Gfx::SE_ACCESS_TRANSFER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_TRANSFER_BIT); lightEnv.numDirectionalLights = dirs.size(); lightEnv.numPointLights = points.size(); @@ -87,7 +90,7 @@ void LightEnvironment::commit() { .numElements = points.size(), }); - lightEnvBuffer->pipelineBarrier(Gfx::SE_ACCESS_TRANSFER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_TRANSFER_BIT, Gfx::SE_ACCESS_SHADER_READ_BIT, + lightEnvBuffer->pipelineBarrier(Gfx::SE_ACCESS_TRANSFER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_TRANSFER_BIT, Gfx::SE_ACCESS_UNIFORM_READ_BIT, Gfx::SE_PIPELINE_STAGE_ALL_COMMANDS_BIT); pointLights->pipelineBarrier(Gfx::SE_ACCESS_TRANSFER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_TRANSFER_BIT, Gfx::SE_ACCESS_SHADER_READ_BIT, Gfx::SE_PIPELINE_STAGE_ALL_COMMANDS_BIT); diff --git a/src/Engine/ThreadPool.cpp b/src/Engine/ThreadPool.cpp index d670570..11fc4ab 100644 --- a/src/Engine/ThreadPool.cpp +++ b/src/Engine/ThreadPool.cpp @@ -1,7 +1,12 @@ #include "ThreadPool.h" +#include "MinimalEngine.h" using namespace Seele; +Globals globals; + +Globals& Seele::getGlobals() { return globals; } + ThreadPool::ThreadPool(uint32 numWorkers) { for (uint32 i = 0; i < numWorkers; ++i) { workers.add(std::thread(&ThreadPool::work, this)); diff --git a/src/Engine/ThreadPool.h b/src/Engine/ThreadPool.h index 48e27fd..778f478 100644 --- a/src/Engine/ThreadPool.h +++ b/src/Engine/ThreadPool.h @@ -4,7 +4,6 @@ #include #include - namespace Seele { class ThreadPool { public: diff --git a/src/Engine/Window/GameView.cpp b/src/Engine/Window/GameView.cpp index f0385ca..4562cb4 100644 --- a/src/Engine/Window/GameView.cpp +++ b/src/Engine/Window/GameView.cpp @@ -6,24 +6,19 @@ #include "Graphics/Query.h" #include "Graphics/RenderPass/BasePass.h" #include "Graphics/RenderPass/CachedDepthPass.h" -#include "Graphics/RenderPass/DebugPass.h" #include "Graphics/RenderPass/DepthCullingPass.h" #include "Graphics/RenderPass/LightCullingPass.h" #include "Graphics/RenderPass/RenderGraphResources.h" -#include "Graphics/RenderPass/SkyboxRenderPass.h" #include "Graphics/RenderPass/VisibilityPass.h" #include "System/CameraUpdater.h" #include "System/LightGather.h" #include "System/MeshUpdater.h" #include "Window/Window.h" #include +#include using namespace Seele; -bool usePositionOnly = false; -bool useDepthCulling = false; -bool useLightCulling = false; - GameView::GameView(Gfx::PGraphics graphics, PWindow window, const ViewportCreateInfo& createInfo, std::string dllPath) : View(graphics, window, createInfo, "Game"), scene(new Scene(graphics)), gameInterface(dllPath) { reloadGame(); @@ -32,48 +27,8 @@ GameView::GameView(Gfx::PGraphics graphics, PWindow window, const ViewportCreate renderGraph.addPass(new VisibilityPass(graphics, scene)); renderGraph.addPass(new LightCullingPass(graphics, scene)); renderGraph.addPass(new BasePass(graphics, scene)); - renderGraph.addPass(new DebugPass(graphics, scene)); - // renderGraph.addPass(new SkyboxRenderPass(graphics, scene)); renderGraph.setViewport(viewport); renderGraph.createRenderPass(); - queryThread = std::thread([&]() { - PRenderGraphResources res = renderGraph.getResources(); - Gfx::PPipelineStatisticsQuery cachedQuery = res->requestQuery("CACHED_QUERY"); - Gfx::PPipelineStatisticsQuery depthQuery = res->requestQuery("DEPTH_QUERY"); - Gfx::PPipelineStatisticsQuery baseQuery = res->requestQuery("BASEPASS_QUERY"); - Gfx::PPipelineStatisticsQuery lightCullQuery = res->requestQuery("LIGHTCULL_QUERY"); - Gfx::PPipelineStatisticsQuery visibilityQuery = res->requestQuery("VISIBILITY_QUERY"); - Gfx::PTimestampQuery timeQuery = res->requestTimestampQuery("TIMESTAMP"); - std::ofstream stats("stats.csv"); - stats << "RelTime," - << "CachedIAV,CachedIAP,CachedVS,CachedClipInv,CachedClipPrim,CachedFS,CachedCS,CachedTS,CachedMS," - << "DepthIAV,DepthIAP,DepthVS,DepthClipInv,DepthClipPrim,DepthFS,DepthCS,DepthTS,DepthMS," - << "BaseIAV,BaseIAP,BaseVS,BaseClipInv,BaseClipPrim,BaseFS,BaseCS,BaseTS,BaseMS," - << "LightCullIAV,LightCullIAP,LightCullVS,LightCullClipInv,LightCullClipPrim,LightCullFS,LightCullCS,LightCullTS,LightCullMS," - << "VisibilityIAV,VisibilityIAP,VisibilityVS,VisibilityClipInv,VisibilityClipPrim,VisibilityFS,VisibilityCS,VisibilityTS," - "VisibilityMS," - << "CACHED,MIPGEN,DEPTHCULL,VISIBILITY,LIGHTCULL,BASE" << std::endl; - std::chrono::nanoseconds start = std::chrono::nanoseconds(0); - while (true) { - auto timestamps = timeQuery->getResults(); - auto cachedResults = cachedQuery->getResults(); - auto depthResults = depthQuery->getResults(); - auto baseResults = baseQuery->getResults(); - auto lightCullResults = lightCullQuery->getResults(); - auto visiblityResults = visibilityQuery->getResults(); - if (start.count() == 0) { - start = timestamps[0].time; - } - stats << (timestamps[0].time - start).count() << "," << cachedResults << depthResults << baseResults << lightCullResults - << visiblityResults; - stats << fmt::format("{},{},{},{},{},{}", (timestamps[1].time - timestamps[0].time).count(), - (timestamps[2].time - timestamps[1].time).count(), (timestamps[3].time - timestamps[2].time).count(), - (timestamps[4].time - timestamps[3].time).count(), (timestamps[5].time - timestamps[4].time).count(), - (timestamps[6].time - timestamps[5].time).count()) - << std::endl; - stats.flush(); - } - }); } GameView::~GameView() {} @@ -127,18 +82,6 @@ void GameView::reloadGame() { void GameView::keyCallback(KeyCode code, InputAction action, KeyModifier modifier) { keyboardSystem->keyCallback(code, action, modifier); - if (code == KeyCode::KEY_P && action == InputAction::RELEASE) { - usePositionOnly = !usePositionOnly; - std::cout << "Use Pos only " << usePositionOnly << std::endl; - } - if (code == KeyCode::KEY_O && action == InputAction::RELEASE) { - useDepthCulling = !useDepthCulling; - std::cout << "Use Depth Culling " << useDepthCulling << std::endl; - } - if (code == KeyCode::KEY_L && action == InputAction::RELEASE) { - useLightCulling = !useLightCulling; - std::cout << "Use Light Culling " << useLightCulling << std::endl; - } } void GameView::mouseMoveCallback(double xPos, double yPos) { keyboardSystem->mouseCallback(xPos, yPos); } diff --git a/src/Engine/Window/GameView.h b/src/Engine/Window/GameView.h index 230d36c..7fb949d 100644 --- a/src/Engine/Window/GameView.h +++ b/src/Engine/Window/GameView.h @@ -28,7 +28,6 @@ class GameView : public View { OScene scene; GameInterface gameInterface; RenderGraph renderGraph; - std::thread queryThread; PSystemGraph systemGraph; System::PKeyboardInput keyboardSystem;