fix: alot of stuff changed. Mostly bugfixxes / architechture changes

This commit is contained in:
2026-08-09 02:24:17 +02:00
parent 4b6f773c0c
commit 05384debbf
98 changed files with 5461 additions and 1751 deletions
+80 -23
View File
@@ -2,6 +2,10 @@
#include <destrum/Graphics/Util.h>
#include <algorithm>
#include <numeric>
#include "volk.h"
#include "destrum/Util/GameState.h"
#include "spdlog/spdlog.h"
@@ -13,26 +17,31 @@ GameRenderer::GameRenderer()
void GameRenderer::init(GfxDevice& gfxDevice, RenderResources& _resources, glm::ivec2 drawImageSize)
{
resources = &_resources;
sceneDataBuffer.init(
gfxDevice,
VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT,
sizeof(GPUSceneData),
"scene data");
try {
resources = &_resources;
sceneDataBuffer.init(
gfxDevice,
VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT,
sizeof(GPUSceneData),
"scene data");
createDrawImage(gfxDevice, drawImageSize, true);
createDrawImage(gfxDevice, drawImageSize, true);
meshPipeline = std::make_unique<MeshPipeline>();
meshPipeline->init(gfxDevice, _resources, drawImageFormat, depthImageFormat);
meshPipeline = std::make_unique<MeshPipeline>();
meshPipeline->init(gfxDevice, _resources, drawImageFormat, depthImageFormat);
skyboxPipeline = std::make_unique<SkyboxPipeline>();
skyboxPipeline->init(gfxDevice, _resources, drawImageFormat, depthImageFormat);
skyboxPipeline = std::make_unique<SkyboxPipeline>();
skyboxPipeline->init(gfxDevice, _resources, drawImageFormat, depthImageFormat);
skinningPipeline = std::make_unique<SkinningPipeline>();
skinningPipeline->init(gfxDevice);
skinningPipeline = std::make_unique<SkinningPipeline>();
skinningPipeline->init(gfxDevice);
GameState::GetInstance().SetRenderer(this);
GameState::GetInstance().SetRenderer(this);
initialized = true;
} catch (...) {
cleanup(gfxDevice);
throw;
}
}
void GameRenderer::beginDrawing(GfxDevice& gfxDevice)
@@ -44,7 +53,23 @@ void GameRenderer::beginDrawing(GfxDevice& gfxDevice)
void GameRenderer::endDrawing()
{
//Sort the drawlist
sortedMeshDrawCommands.resize(meshDrawCommands.size());
std::iota(sortedMeshDrawCommands.begin(), sortedMeshDrawCommands.end(), 0);
std::stable_sort(
sortedMeshDrawCommands.begin(),
sortedMeshDrawCommands.end(),
[this](std::size_t left, std::size_t right) {
const auto& lhs = meshDrawCommands[left];
const auto& rhs = meshDrawCommands[right];
if (lhs.meshId != rhs.meshId) {
return lhs.meshId < rhs.meshId;
}
if (lhs.materialId != rhs.materialId) {
return lhs.materialId < rhs.materialId;
}
return (lhs.skinnedMesh != nullptr) < (rhs.skinnedMesh != nullptr);
});
}
void GameRenderer::draw(VkCommandBuffer cmd, GfxDevice& gfxDevice, const Camera& camera, const SceneData& sceneData)
@@ -55,6 +80,11 @@ void GameRenderer::draw(VkCommandBuffer cmd, GfxDevice& gfxDevice, const Camera&
{
TracyVkZone(gfxDevice.getTracyVkCtx(), cmd, "Skinning");
skinningPipeline->flushCurrentFrame(
cmd,
gfxDevice,
gfxDevice.getCurrentFrameIndex());
for (const auto& dc : meshDrawCommands)
{
if (!dc.skinnedMesh)
@@ -108,8 +138,9 @@ void GameRenderer::draw(VkCommandBuffer cmd, GfxDevice& gfxDevice, const Camera&
vkutil::transitionImage(
cmd,
drawImage.image,
VK_IMAGE_LAYOUT_UNDEFINED,
drawImage.layout,
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
drawImage.setLayout(VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
}
{
@@ -118,17 +149,20 @@ void GameRenderer::draw(VkCommandBuffer cmd, GfxDevice& gfxDevice, const Camera&
vkutil::transitionImage(
cmd,
depthImage.image,
VK_IMAGE_LAYOUT_UNDEFINED,
depthImage.layout,
VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL);
depthImage.setLayout(VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL);
}
const auto renderInfo = vkutil::createRenderingInfo({
auto renderInfo = vkutil::createRenderingInfo({
.renderExtent = drawImage.getExtent2D(),
.colorImageView = drawImage.imageView,
.colorImageClearValue = glm::vec4{0.f, 0.f, 0.f, 1.f},
.depthImageView = depthImage.imageView,
.depthImageClearValue = 1.f,
});
renderInfo.renderingInfo.pColorAttachments = &renderInfo.colorAttachment;
renderInfo.renderingInfo.pDepthAttachment = &renderInfo.depthAttachment;
{
TracyVkZone(gfxDevice.getTracyVkCtx(), cmd, "vkCmdBeginRendering");
@@ -165,9 +199,11 @@ void GameRenderer::draw(VkCommandBuffer cmd, GfxDevice& gfxDevice, const Camera&
void GameRenderer::cleanup(GfxDevice& gfxDevice)
{
VkDevice device = gfxDevice.getDevice().device;
VkDevice device = gfxDevice.getDevice();
vkDeviceWaitIdle(device);
if (device != VK_NULL_HANDLE) {
vkDeviceWaitIdle(device);
}
if (skinningPipeline)
skinningPipeline->cleanup(gfxDevice);
@@ -188,6 +224,15 @@ void GameRenderer::cleanup(GfxDevice& gfxDevice)
drawImageId = NULL_IMAGE_ID;
depthImageId = NULL_IMAGE_ID;
resources = nullptr;
meshPipeline.reset();
skyboxPipeline.reset();
skinningPipeline.reset();
pendingMaterialUploads.clear();
meshDrawCommands.clear();
sortedMeshDrawCommands.clear();
initialized = false;
GameState::GetInstance().SetRenderer(nullptr);
}
void GameRenderer::drawMesh(MeshID id, const glm::mat4& transform, MaterialID materialId)
@@ -199,6 +244,7 @@ void GameRenderer::drawMesh(MeshID id, const glm::mat4& transform, MaterialID ma
meshDrawCommands.push_back(MeshDrawCommand{
.meshId = id,
.transformMatrix = transform,
.worldBoundingSphere = worldBoundingSphere,
.materialId = materialId,
});
}
@@ -210,13 +256,14 @@ void GameRenderer::drawSkinnedMesh(MeshID id,
std::size_t jointMatricesStartIndex)
{
const auto& mesh = resources->meshes().getMesh(id);
const auto worldBoundingSphere = edge::calculateBoundingSphereWorld(transform, mesh.boundingSphere, false);
const auto worldBoundingSphere = edge::calculateBoundingSphereWorld(transform, mesh.boundingSphere, true);
assert(materialId != NULL_MATERIAL_ID);
assert(skinnedMesh != nullptr);
meshDrawCommands.push_back(MeshDrawCommand{
.meshId = id,
.transformMatrix = transform,
.worldBoundingSphere = worldBoundingSphere,
.materialId = materialId,
.skinnedMesh = skinnedMesh,
.jointMatricesStartIndex = static_cast<std::uint32_t>(jointMatricesStartIndex),
@@ -249,10 +296,20 @@ void GameRenderer::setSkyboxTexture(ImageID skyboxImageId)
void GameRenderer::flushMaterialUpdates(GfxDevice& gfxDevice)
{
if (!pendingMaterialUploads.empty()) {
// Material data is currently shared by all frame contexts. Wait before
// mutating it so an older in-flight frame cannot read the overwritten
// range. This can later be replaced with per-frame material buffers.
gfxDevice.waitIdle();
}
for (MaterialID id : pendingMaterialUploads)
{
resources->materials().updateMaterialGPU(id);
// if non-coherent: flush mapped range for that id here
gfxDevice.getMemoryManager().flushAllocation(
resources->materials().getMaterialDataBuffer(),
static_cast<VkDeviceSize>(id) * sizeof(MaterialData),
sizeof(MaterialData));
}
pendingMaterialUploads.clear();
}