Clean up some code by moving it into functions

This commit is contained in:
Magnus Norddahl 2022-08-31 06:15:37 +02:00
parent 66124477b2
commit 59c58b75f1
2 changed files with 251 additions and 220 deletions

View file

@ -43,43 +43,47 @@ void GPURaytracer2::Raytrace(LevelMesh* level)
printf("Ray tracing in progress...\n");
CreateAtlasImages();
BeginCommands();
UploadUniforms();
Uniforms2 uniforms = {};
uniforms.SunDir = mesh->map->GetSunDirection();
uniforms.SunColor = mesh->map->GetSunColor();
uniforms.SunIntensity = 1.0f;
mappedUniforms = (uint8_t*)uniformTransferBuffer->Map(0, uniformStructs * uniformStructStride);
*reinterpret_cast<Uniforms2*>(mappedUniforms + uniformStructStride * uniformsIndex) = uniforms;
uniformTransferBuffer->Unmap();
cmdbuffer->copyBuffer(uniformTransferBuffer.get(), uniformBuffer.get());
PipelineBarrier()
.AddBuffer(uniformBuffer.get(), VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT)
.Execute(cmdbuffer.get(), VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
const int atlasImageSize = 2048;
const int spacing = 3; // Note: the spacing is here to avoid that the resolve sampler finds data from other surface tiles
RectPacker packer(atlasImageSize, atlasImageSize, RectPacker::Spacing(spacing));
for (size_t i = 0; i < mesh->surfaces.size(); i++)
for (size_t pageIndex = 0; pageIndex < atlasImages.size(); pageIndex++)
{
Surface* surface = mesh->surfaces[i].get();
auto result = packer.insert(surface->texWidth + 2, surface->texHeight + 2);
surface->atlasX = result.pos.x + 1;
surface->atlasY = result.pos.y + 1;
surface->atlasPageIndex = (int)result.pageIndex;
}
std::vector<LightmapImage> atlasImages;
for (size_t pageIndex = 0; pageIndex < packer.getNumPages(); pageIndex++)
{
atlasImages.push_back(CreateImage(atlasImageSize, atlasImageSize));
RenderAtlasImage(pageIndex);
}
for (size_t pageIndex = 0; pageIndex < atlasImages.size(); pageIndex++)
{
ResolveAtlasImage(pageIndex);
}
#ifdef WIN32
LARGE_INTEGER s;
QueryPerformanceCounter(&s);
#endif
FinishCommands();
#ifdef WIN32
LARGE_INTEGER e, f;
QueryPerformanceCounter(&e);
QueryPerformanceFrequency(&f);
printf("GPU ray tracing time was %.3f seconds.\n", double(e.QuadPart - s.QuadPart) / double(f.QuadPart));
#endif
for (size_t pageIndex = 0; pageIndex < atlasImages.size(); pageIndex++)
{
DownloadAtlasImage(pageIndex);
}
if (device->renderdoc)
device->renderdoc->EndFrameCapture(0, 0);
printf("Ray trace complete\n");
}
void GPURaytracer2::RenderAtlasImage(size_t pageIndex)
{
LightmapImage& img = atlasImages[pageIndex];
@ -172,10 +176,49 @@ void GPURaytracer2::Raytrace(LevelMesh* level)
cmdbuffer->draw(vertexCount, 1, firstVertex, 0);
}
}
cmdbuffer->endRenderPass();
}
for (size_t i = 0; i < atlasImages.size(); i++)
void GPURaytracer2::CreateAtlasImages()
{
const int spacing = 3; // Note: the spacing is here to avoid that the resolve sampler finds data from other surface tiles
RectPacker packer(atlasImageSize, atlasImageSize, RectPacker::Spacing(spacing));
for (size_t i = 0; i < mesh->surfaces.size(); i++)
{
Surface* surface = mesh->surfaces[i].get();
auto result = packer.insert(surface->texWidth + 2, surface->texHeight + 2);
surface->atlasX = result.pos.x + 1;
surface->atlasY = result.pos.y + 1;
surface->atlasPageIndex = (int)result.pageIndex;
}
for (size_t pageIndex = 0; pageIndex < packer.getNumPages(); pageIndex++)
{
atlasImages.push_back(CreateImage(atlasImageSize, atlasImageSize));
}
}
void GPURaytracer2::UploadUniforms()
{
Uniforms2 uniforms = {};
uniforms.SunDir = mesh->map->GetSunDirection();
uniforms.SunColor = mesh->map->GetSunColor();
uniforms.SunIntensity = 1.0f;
mappedUniforms = (uint8_t*)uniformTransferBuffer->Map(0, uniformStructs * uniformStructStride);
*reinterpret_cast<Uniforms2*>(mappedUniforms + uniformStructStride * uniformsIndex) = uniforms;
uniformTransferBuffer->Unmap();
cmdbuffer->copyBuffer(uniformTransferBuffer.get(), uniformBuffer.get());
PipelineBarrier()
.AddBuffer(uniformBuffer.get(), VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT)
.Execute(cmdbuffer.get(), VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
}
void GPURaytracer2::ResolveAtlasImage(size_t i)
{
LightmapImage& img = atlasImages[i];
@ -241,28 +284,14 @@ void GPURaytracer2::Raytrace(LevelMesh* level)
cmdbuffer->copyImageToBuffer(img.resolve.Image->image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, img.Transfer->buffer, 1, &region);
}
#ifdef WIN32
LARGE_INTEGER s;
QueryPerformanceCounter(&s);
#endif
FinishCommands();
#ifdef WIN32
LARGE_INTEGER e, f;
QueryPerformanceCounter(&e);
QueryPerformanceFrequency(&f);
printf("GPU ray tracing time was %.3f seconds.\n", double(e.QuadPart - s.QuadPart) / double(f.QuadPart));
#endif
void GPURaytracer2::DownloadAtlasImage(size_t pageIndex)
{
struct hvec4
{
unsigned short x, y, z, w;
vec3 xyz() { return vec3(halfToFloat(x), halfToFloat(y), halfToFloat(z)); }
};
for (size_t pageIndex = 0; pageIndex < atlasImages.size(); pageIndex++)
{
hvec4* pixels = (hvec4*)atlasImages[pageIndex].Transfer->Map(0, atlasImageSize * atlasImageSize * sizeof(hvec4));
for (size_t i = 0; i < mesh->surfaces.size(); i++)
@ -276,7 +305,6 @@ void GPURaytracer2::Raytrace(LevelMesh* level)
int sampleWidth = surface->texWidth;
int sampleHeight = surface->texHeight;
// Download
for (int y = 0; y < sampleHeight; y++)
{
vec3* dest = &surface->texPixels[y * sampleWidth];
@ -290,12 +318,6 @@ void GPURaytracer2::Raytrace(LevelMesh* level)
atlasImages[pageIndex].Transfer->Unmap();
}
if (device->renderdoc)
device->renderdoc->EndFrameCapture(0, 0);
printf("Ray trace complete\n");
}
vec2 GPURaytracer2::ToUV(const vec3& vert, const Surface* targetSurface)
{
vec3 localPos = vert - targetSurface->translateWorldToLocal;

View file

@ -97,6 +97,12 @@ private:
void CreateSceneVertexBuffer();
void CreateSceneLightBuffer();
void UploadUniforms();
void CreateAtlasImages();
void RenderAtlasImage(size_t pageIndex);
void ResolveAtlasImage(size_t pageIndex);
void DownloadAtlasImage(size_t pageIndex);
LightmapImage CreateImage(int width, int height);
void BeginCommands();
@ -175,4 +181,7 @@ private:
std::unique_ptr<VulkanFence> submitFence;
std::unique_ptr<VulkanCommandPool> cmdpool;
std::unique_ptr<VulkanCommandBuffer> cmdbuffer;
std::vector<LightmapImage> atlasImages;
static const int atlasImageSize = 2048;
};