Flush scene buffers if next surface is out of space

This commit is contained in:
RaveYard 2022-10-15 18:32:27 +02:00
parent 8fb35aca7f
commit 7aff36dfb4

View file

@ -97,17 +97,20 @@ void GPURaytracer::RenderAtlasImage(size_t pageIndex)
{ {
LightmapImage& img = atlasImages[pageIndex]; LightmapImage& img = atlasImages[pageIndex];
RenderPassBegin() const auto beginPass = [&]() {
.RenderPass(raytrace.renderPass.get()) RenderPassBegin()
.RenderArea(0, 0, atlasImageSize, atlasImageSize) .RenderPass(raytrace.renderPass.get())
.Framebuffer(img.raytrace.Framebuffer.get()) .RenderArea(0, 0, atlasImageSize, atlasImageSize)
.Execute(cmdbuffer.get()); .Framebuffer(img.raytrace.Framebuffer.get())
.Execute(cmdbuffer.get());
VkDeviceSize offset = 0; VkDeviceSize offset = 0;
cmdbuffer->bindVertexBuffers(0, 1, &sceneVertexBuffer->buffer, &offset); cmdbuffer->bindVertexBuffers(0, 1, &sceneVertexBuffer->buffer, &offset);
cmdbuffer->bindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, raytrace.pipeline.get()); cmdbuffer->bindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, raytrace.pipeline.get());
cmdbuffer->bindDescriptorSet(VK_PIPELINE_BIND_POINT_GRAPHICS, raytrace.pipelineLayout.get(), 0, raytrace.descriptorSet0.get()); cmdbuffer->bindDescriptorSet(VK_PIPELINE_BIND_POINT_GRAPHICS, raytrace.pipelineLayout.get(), 0, raytrace.descriptorSet0.get());
cmdbuffer->bindDescriptorSet(VK_PIPELINE_BIND_POINT_GRAPHICS, raytrace.pipelineLayout.get(), 1, raytrace.descriptorSet1.get()); cmdbuffer->bindDescriptorSet(VK_PIPELINE_BIND_POINT_GRAPHICS, raytrace.pipelineLayout.get(), 1, raytrace.descriptorSet1.get());
};
beginPass();
for (size_t i = 0; i < mesh->surfaces.size(); i++) for (size_t i = 0; i < mesh->surfaces.size(); i++)
{ {
@ -135,10 +138,29 @@ void GPURaytracer::RenderAtlasImage(size_t pageIndex)
continue; // Bounding box not visible continue; // Bounding box not visible
int firstLight = sceneLightPos; int firstLight = sceneLightPos;
int firstVertex = sceneVertexPos;
int lightCount = (int)surface->LightList.size(); int lightCount = (int)surface->LightList.size();
if (sceneLightPos + lightCount > SceneLightBufferSize) int vertexCount = (int)surface->verts.size();
throw std::runtime_error("SceneLightBuffer is too small!"); if (sceneLightPos + lightCount > SceneLightBufferSize || sceneVertexPos + vertexCount > SceneVertexBufferSize)
{
// Flush scene buffers
FinishCommands();
sceneLightPos = 0;
sceneVertexPos = 0;
BeginCommands();
beginPass();
if (sceneLightPos + lightCount > SceneLightBufferSize)
{
throw std::runtime_error("SceneLightBuffer is too small!");
}
else if (sceneVertexPos + vertexCount > SceneVertexBufferSize)
{
throw std::runtime_error("SceneVertexBuffer is too small!");
}
}
sceneLightPos += lightCount; sceneLightPos += lightCount;
sceneVertexPos += vertexCount;
LightInfo* lightinfo = &sceneLights[firstLight]; LightInfo* lightinfo = &sceneLights[firstLight];
for (ThingLight* light : surface->LightList) for (ThingLight* light : surface->LightList)
@ -162,11 +184,6 @@ void GPURaytracer::RenderAtlasImage(size_t pageIndex)
pc.LightmapStepY = targetSurface->worldStepY * viewport.height; pc.LightmapStepY = targetSurface->worldStepY * viewport.height;
cmdbuffer->pushConstants(raytrace.pipelineLayout.get(), VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(PushConstants), &pc); cmdbuffer->pushConstants(raytrace.pipelineLayout.get(), VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(PushConstants), &pc);
int firstVertex = sceneVertexPos;
int vertexCount = (int)surface->verts.size();
if (sceneVertexPos + vertexCount > SceneVertexBufferSize)
throw std::runtime_error("SceneVertexBuffer is too small!");
sceneVertexPos += vertexCount;
SceneVertex* vertex = &sceneVertices[firstVertex]; SceneVertex* vertex = &sceneVertices[firstVertex];
if (surface->type == ST_FLOOR || surface->type == ST_CEILING) if (surface->type == ST_FLOOR || surface->type == ST_CEILING)