fix: alot of stuff changed. Mostly bugfixxes / architechture changes
This commit is contained in:
@@ -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();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user