mirror of
https://github.com/ZDoom/ZDRay.git
synced 2025-02-03 05:01:00 +00:00
Implement enough of a ray query raytracer that it at least outputs something
This commit is contained in:
parent
12ffde80bc
commit
65445a7b07
8 changed files with 188 additions and 74 deletions
|
@ -46,8 +46,16 @@ layout(push_constant) uniform PushConstants
|
||||||
{
|
{
|
||||||
uint LightStart;
|
uint LightStart;
|
||||||
uint LightEnd;
|
uint LightEnd;
|
||||||
int surfaceIndex;
|
int SurfaceIndex;
|
||||||
int pushPadding;
|
int PushPadding1;
|
||||||
|
vec2 TileTL;
|
||||||
|
vec2 TileBR;
|
||||||
|
vec3 LightmapOrigin;
|
||||||
|
float PushPadding2;
|
||||||
|
vec3 LightmapStepX;
|
||||||
|
float PushPadding3;
|
||||||
|
vec3 LightmapStepY;
|
||||||
|
float PushPadding4;
|
||||||
};
|
};
|
||||||
|
|
||||||
layout(location = 0) in vec3 worldpos;
|
layout(location = 0) in vec3 worldpos;
|
||||||
|
@ -59,12 +67,13 @@ void main()
|
||||||
|
|
||||||
vec3 origin = worldpos;
|
vec3 origin = worldpos;
|
||||||
vec3 normal;
|
vec3 normal;
|
||||||
if (surfaceIndex >= 0)
|
if (SurfaceIndex >= 0)
|
||||||
{
|
{
|
||||||
normal = surfaces[surfaceIndex].Normal;
|
normal = surfaces[SurfaceIndex].Normal;
|
||||||
origin += normal * 0.1;
|
origin += normal * 0.1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vec3 incoming = vec3(0.0);
|
||||||
for (uint j = LightStart; j < LightEnd; j++)
|
for (uint j = LightStart; j < LightEnd; j++)
|
||||||
{
|
{
|
||||||
LightInfo light = lights[j];
|
LightInfo light = lights[j];
|
||||||
|
@ -76,7 +85,7 @@ void main()
|
||||||
|
|
||||||
float distAttenuation = max(1.0 - (dist / light.Radius), 0.0);
|
float distAttenuation = max(1.0 - (dist / light.Radius), 0.0);
|
||||||
float angleAttenuation = 1.0f;
|
float angleAttenuation = 1.0f;
|
||||||
if (surfaceIndex >= 0)
|
if (SurfaceIndex >= 0)
|
||||||
{
|
{
|
||||||
angleAttenuation = max(dot(normal, dir), 0.0);
|
angleAttenuation = max(dot(normal, dir), 0.0);
|
||||||
}
|
}
|
||||||
|
@ -98,13 +107,13 @@ void main()
|
||||||
|
|
||||||
if (rayQueryGetIntersectionTypeEXT(rayQuery, true) == gl_RayQueryCommittedIntersectionNoneEXT)
|
if (rayQueryGetIntersectionTypeEXT(rayQuery, true) == gl_RayQueryCommittedIntersectionNoneEXT)
|
||||||
{
|
{
|
||||||
incoming.rgb += light.Color * (attenuation * light.Intensity) * incoming.w;
|
incoming.rgb += light.Color * (attenuation * light.Intensity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fragcolor = vec4(0.0);
|
fragcolor = vec4(incoming, 1.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
)glsl";
|
)glsl";
|
||||||
|
|
|
@ -2,20 +2,20 @@ static const char* glsl_vert = R"glsl(
|
||||||
|
|
||||||
#version 460
|
#version 460
|
||||||
|
|
||||||
layout(set = 0, binding = 1) uniform Uniforms
|
|
||||||
{
|
|
||||||
vec3 SunDir;
|
|
||||||
float Padding1;
|
|
||||||
vec3 SunColor;
|
|
||||||
float SunIntensity;
|
|
||||||
};
|
|
||||||
|
|
||||||
layout(push_constant) uniform PushConstants
|
layout(push_constant) uniform PushConstants
|
||||||
{
|
{
|
||||||
uint LightStart;
|
uint LightStart;
|
||||||
uint LightEnd;
|
uint LightEnd;
|
||||||
int surfaceIndex;
|
int SurfaceIndex;
|
||||||
int pushPadding;
|
int PushPadding1;
|
||||||
|
vec2 TileTL;
|
||||||
|
vec2 TileBR;
|
||||||
|
vec3 LightmapOrigin;
|
||||||
|
float PushPadding2;
|
||||||
|
vec3 LightmapStepX;
|
||||||
|
float PushPadding3;
|
||||||
|
vec3 LightmapStepY;
|
||||||
|
float PushPadding4;
|
||||||
};
|
};
|
||||||
|
|
||||||
layout(location = 0) out vec3 worldpos;
|
layout(location = 0) out vec3 worldpos;
|
||||||
|
@ -29,8 +29,9 @@ vec2 positions[4] = vec2[](
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
worldpos = vec3(0.0);
|
vec2 tilepos = positions[gl_VertexIndex];
|
||||||
gl_Position = vec4(positions[gl_VertexIndex] * 2.0 - 1.0, 0.0, 1.0);
|
worldpos = LightmapOrigin + LightmapStepX * tilepos.x + LightmapStepY * tilepos.y;
|
||||||
|
gl_Position = vec4(mix(TileTL, TileBR, tilepos) * 2.0 - 1.0, 0.0, 1.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
)glsl";
|
)glsl";
|
||||||
|
|
|
@ -42,7 +42,77 @@ void GPURaytracer2::Raytrace(LevelMesh* level)
|
||||||
|
|
||||||
printf("Ray tracing in progress...\n");
|
printf("Ray tracing in progress...\n");
|
||||||
|
|
||||||
|
BeginCommands();
|
||||||
|
|
||||||
|
std::vector<LightmapImage> surfaceImages;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < mesh->surfaces.size(); i++)
|
||||||
|
{
|
||||||
|
Surface* surface = mesh->surfaces[i].get();
|
||||||
|
int sampleWidth = surface->lightmapDims[0];
|
||||||
|
int sampleHeight = surface->lightmapDims[1];
|
||||||
|
|
||||||
|
LightmapImage img = CreateImage(sampleWidth, sampleHeight);
|
||||||
|
|
||||||
|
RenderPassBegin()
|
||||||
|
.RenderPass(renderPass.get())
|
||||||
|
.RenderArea(0, 0, sampleWidth, sampleHeight)
|
||||||
|
.Framebuffer(img.Framebuffer.get())
|
||||||
|
.Execute(cmdbuffer.get());
|
||||||
|
|
||||||
|
PushConstants2 pc;
|
||||||
|
pc.LightStart = 0;
|
||||||
|
pc.LightEnd = mesh->map->ThingLights.Size();
|
||||||
|
pc.SurfaceIndex = (int32_t)i;
|
||||||
|
pc.TileTL = vec2(0.0f);
|
||||||
|
pc.TileBR = vec2(1.0f);
|
||||||
|
pc.LightmapOrigin = surface->lightmapOrigin;
|
||||||
|
pc.LightmapStepX = surface->lightmapSteps[0] * (float)sampleWidth;
|
||||||
|
pc.LightmapStepY = surface->lightmapSteps[1] * (float)sampleHeight;
|
||||||
|
|
||||||
|
VkViewport viewport = {};
|
||||||
|
viewport.maxDepth = 1;
|
||||||
|
viewport.width = (float)sampleWidth;
|
||||||
|
viewport.height = (float)sampleHeight;
|
||||||
|
cmdbuffer->setViewport(0, 1, &viewport);
|
||||||
|
|
||||||
|
cmdbuffer->bindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline.get());
|
||||||
|
cmdbuffer->bindDescriptorSet(VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout.get(), 0, descriptorSet.get());
|
||||||
|
cmdbuffer->pushConstants(pipelineLayout.get(), VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(PushConstants2), &pc);
|
||||||
|
cmdbuffer->draw(4, 1, 0, 0);
|
||||||
|
|
||||||
|
cmdbuffer->endRenderPass();
|
||||||
|
|
||||||
|
PipelineBarrier()
|
||||||
|
.AddImage(img.Image.get(), VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT)
|
||||||
|
.Execute(cmdbuffer.get(), VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
|
||||||
|
|
||||||
|
VkBufferImageCopy region = {};
|
||||||
|
region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||||
|
region.imageSubresource.layerCount = 1;
|
||||||
|
region.imageExtent.width = sampleWidth;
|
||||||
|
region.imageExtent.height = sampleHeight;
|
||||||
|
region.imageExtent.depth = 1;
|
||||||
|
cmdbuffer->copyImageToBuffer(img.Image->image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, img.Transfer->buffer, 1, ®ion);
|
||||||
|
|
||||||
|
surfaceImages.push_back(std::move(img));
|
||||||
|
}
|
||||||
|
|
||||||
|
FinishCommands();
|
||||||
|
|
||||||
|
for (size_t i = 0; i < mesh->surfaces.size(); i++)
|
||||||
|
{
|
||||||
|
Surface* surface = mesh->surfaces[i].get();
|
||||||
|
int sampleWidth = surface->lightmapDims[0];
|
||||||
|
int sampleHeight = surface->lightmapDims[1];
|
||||||
|
|
||||||
|
vec4* pixels = (vec4*)surfaceImages[i].Transfer->Map(0, sampleWidth * sampleHeight * sizeof(vec4));
|
||||||
|
for (int i = 0; i < sampleWidth * sampleHeight; i++)
|
||||||
|
{
|
||||||
|
surface->samples[i] = pixels[i].xyz();
|
||||||
|
}
|
||||||
|
surfaceImages[i].Transfer->Unmap();
|
||||||
|
}
|
||||||
|
|
||||||
if (device->renderdoc)
|
if (device->renderdoc)
|
||||||
device->renderdoc->EndFrameCapture(0, 0);
|
device->renderdoc->EndFrameCapture(0, 0);
|
||||||
|
@ -62,7 +132,6 @@ void GPURaytracer2::CreateVulkanObjects()
|
||||||
CreateTopLevelAccelerationStructure();
|
CreateTopLevelAccelerationStructure();
|
||||||
CreateShaders();
|
CreateShaders();
|
||||||
CreatePipeline();
|
CreatePipeline();
|
||||||
CreateFrameBuffer();
|
|
||||||
CreateDescriptorSet();
|
CreateDescriptorSet();
|
||||||
|
|
||||||
PipelineBarrier()
|
PipelineBarrier()
|
||||||
|
@ -334,9 +403,10 @@ void GPURaytracer2::CreatePipeline()
|
||||||
{
|
{
|
||||||
descriptorSetLayout = DescriptorSetLayoutBuilder()
|
descriptorSetLayout = DescriptorSetLayoutBuilder()
|
||||||
.AddBinding(0, VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, 1, VK_SHADER_STAGE_FRAGMENT_BIT)
|
.AddBinding(0, VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, 1, VK_SHADER_STAGE_FRAGMENT_BIT)
|
||||||
.AddBinding(1, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 1, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT)
|
.AddBinding(1, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT)
|
||||||
.AddBinding(2, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT)
|
.AddBinding(2, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT)
|
||||||
.AddBinding(3, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT)
|
.AddBinding(3, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT)
|
||||||
|
.AddBinding(4, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT)
|
||||||
.DebugName("descriptorSetLayout")
|
.DebugName("descriptorSetLayout")
|
||||||
.Create(device.get());
|
.Create(device.get());
|
||||||
|
|
||||||
|
@ -348,19 +418,19 @@ void GPURaytracer2::CreatePipeline()
|
||||||
|
|
||||||
renderPass = RenderPassBuilder()
|
renderPass = RenderPassBuilder()
|
||||||
.AddAttachment(
|
.AddAttachment(
|
||||||
VK_FORMAT_R8G8B8A8_UNORM,
|
VK_FORMAT_R32G32B32A32_SFLOAT,
|
||||||
VK_SAMPLE_COUNT_1_BIT,
|
VK_SAMPLE_COUNT_1_BIT,
|
||||||
VK_ATTACHMENT_LOAD_OP_LOAD,
|
VK_ATTACHMENT_LOAD_OP_DONT_CARE,
|
||||||
VK_ATTACHMENT_STORE_OP_STORE,
|
VK_ATTACHMENT_STORE_OP_STORE,
|
||||||
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
|
VK_IMAGE_LAYOUT_UNDEFINED,
|
||||||
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)
|
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)
|
||||||
.AddSubpass()
|
.AddSubpass()
|
||||||
.AddSubpassColorAttachmentRef(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)
|
.AddSubpassColorAttachmentRef(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)
|
||||||
.AddExternalSubpassDependency(
|
.AddExternalSubpassDependency(
|
||||||
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
|
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
|
||||||
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
|
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
|
||||||
VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
|
VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
|
||||||
VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_SHADER_READ_BIT)
|
VK_ACCESS_COLOR_ATTACHMENT_READ_BIT)
|
||||||
.DebugName("renderpass")
|
.DebugName("renderpass")
|
||||||
.Create(device.get());
|
.Create(device.get());
|
||||||
|
|
||||||
|
@ -370,35 +440,43 @@ void GPURaytracer2::CreatePipeline()
|
||||||
.AddVertexShader(vertShader.get())
|
.AddVertexShader(vertShader.get())
|
||||||
.AddFragmentShader(fragShader.get())
|
.AddFragmentShader(fragShader.get())
|
||||||
.Topology(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP)
|
.Topology(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP)
|
||||||
.Viewport(0.0f, 0.0f, 320.0f, 200.0f)
|
.AddDynamicState(VK_DYNAMIC_STATE_VIEWPORT)
|
||||||
.Scissor(0, 0, 320, 200)
|
.Viewport(0.0f, 0.0f, 0.0f, 0.0f)
|
||||||
|
.Scissor(0, 0, 4096, 4096)
|
||||||
.DebugName("pipeline")
|
.DebugName("pipeline")
|
||||||
.Create(device.get());
|
.Create(device.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
void GPURaytracer2::CreateFrameBuffer()
|
LightmapImage GPURaytracer2::CreateImage(int width, int height)
|
||||||
{
|
{
|
||||||
framebufferImage = ImageBuilder()
|
LightmapImage img;
|
||||||
|
|
||||||
|
img.Image = ImageBuilder()
|
||||||
.Usage(VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT)
|
.Usage(VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT)
|
||||||
.Format(VK_FORMAT_R8G8B8A8_UNORM)
|
.Format(VK_FORMAT_R32G32B32A32_SFLOAT)
|
||||||
.Size(320, 200)
|
.Size(width, height)
|
||||||
|
.DebugName("LightmapImage.Image")
|
||||||
.Create(device.get());
|
.Create(device.get());
|
||||||
|
|
||||||
framebufferImageView = ImageViewBuilder()
|
img.View = ImageViewBuilder()
|
||||||
.Image(framebufferImage.get(), VK_FORMAT_R8G8B8A8_UNORM)
|
.Image(img.Image.get(), VK_FORMAT_R32G32B32A32_SFLOAT)
|
||||||
.DebugName("framebufferImageView")
|
.DebugName("LightmapImage.View")
|
||||||
.Create(device.get());
|
.Create(device.get());
|
||||||
|
|
||||||
framebuffer = FramebufferBuilder()
|
img.Framebuffer = FramebufferBuilder()
|
||||||
.RenderPass(renderPass.get())
|
.RenderPass(renderPass.get())
|
||||||
.Size(320, 200)
|
.Size(width, height)
|
||||||
.AddAttachment(framebufferImageView.get())
|
.AddAttachment(img.View.get())
|
||||||
.DebugName("framebuffer")
|
.DebugName("LightmapImage.Framebuffer")
|
||||||
.Create(device.get());
|
.Create(device.get());
|
||||||
|
|
||||||
PipelineBarrier()
|
img.Transfer = BufferBuilder()
|
||||||
.AddImage(framebufferImage.get(), VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 0, VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT)
|
.Size(width * height * sizeof(vec4))
|
||||||
.Execute(cmdbuffer.get(), 0, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT);
|
.Usage(VK_IMAGE_USAGE_TRANSFER_DST_BIT, VMA_MEMORY_USAGE_CPU_ONLY)
|
||||||
|
.DebugName("LightmapImage.Transfer")
|
||||||
|
.Create(device.get());
|
||||||
|
|
||||||
|
return img;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GPURaytracer2::CreateDescriptorSet()
|
void GPURaytracer2::CreateDescriptorSet()
|
||||||
|
@ -420,7 +498,7 @@ void GPURaytracer2::CreateDescriptorSet()
|
||||||
|
|
||||||
descriptorPool = DescriptorPoolBuilder()
|
descriptorPool = DescriptorPoolBuilder()
|
||||||
.AddPoolSize(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, 1)
|
.AddPoolSize(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, 1)
|
||||||
.AddPoolSize(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 1)
|
.AddPoolSize(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1)
|
||||||
.AddPoolSize(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 3)
|
.AddPoolSize(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 3)
|
||||||
.MaxSets(1)
|
.MaxSets(1)
|
||||||
.DebugName("descriptorPool")
|
.DebugName("descriptorPool")
|
||||||
|
@ -431,7 +509,7 @@ void GPURaytracer2::CreateDescriptorSet()
|
||||||
|
|
||||||
WriteDescriptors()
|
WriteDescriptors()
|
||||||
.AddAccelerationStructure(descriptorSet.get(), 0, tlAccelStruct.get())
|
.AddAccelerationStructure(descriptorSet.get(), 0, tlAccelStruct.get())
|
||||||
.AddBuffer(descriptorSet.get(), 1, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, uniformBuffer.get(), 0, sizeof(Uniforms2))
|
.AddBuffer(descriptorSet.get(), 1, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, uniformBuffer.get(), 0, sizeof(Uniforms2))
|
||||||
.AddBuffer(descriptorSet.get(), 2, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, surfaceIndexBuffer.get())
|
.AddBuffer(descriptorSet.get(), 2, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, surfaceIndexBuffer.get())
|
||||||
.AddBuffer(descriptorSet.get(), 3, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, surfaceBuffer.get())
|
.AddBuffer(descriptorSet.get(), 3, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, surfaceBuffer.get())
|
||||||
.AddBuffer(descriptorSet.get(), 4, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, lightBuffer.get())
|
.AddBuffer(descriptorSet.get(), 4, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, lightBuffer.get())
|
||||||
|
|
|
@ -18,8 +18,16 @@ struct PushConstants2
|
||||||
{
|
{
|
||||||
uint32_t LightStart;
|
uint32_t LightStart;
|
||||||
uint32_t LightEnd;
|
uint32_t LightEnd;
|
||||||
int32_t surfaceIndex;
|
int32_t SurfaceIndex;
|
||||||
int32_t pushPadding;
|
int32_t PushPadding1;
|
||||||
|
vec2 TileTL;
|
||||||
|
vec2 TileBR;
|
||||||
|
vec3 LightmapOrigin;
|
||||||
|
float PushPadding2;
|
||||||
|
vec3 LightmapStepX;
|
||||||
|
float PushPadding3;
|
||||||
|
vec3 LightmapStepY;
|
||||||
|
float PushPadding4;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SurfaceInfo2
|
struct SurfaceInfo2
|
||||||
|
@ -47,6 +55,14 @@ struct LightInfo2
|
||||||
float Padding2;
|
float Padding2;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct LightmapImage
|
||||||
|
{
|
||||||
|
std::unique_ptr<VulkanImage> Image;
|
||||||
|
std::unique_ptr<VulkanImageView> View;
|
||||||
|
std::unique_ptr<VulkanFramebuffer> Framebuffer;
|
||||||
|
std::unique_ptr<VulkanBuffer> Transfer;
|
||||||
|
};
|
||||||
|
|
||||||
class GPURaytracer2
|
class GPURaytracer2
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -62,9 +78,10 @@ private:
|
||||||
void CreateTopLevelAccelerationStructure();
|
void CreateTopLevelAccelerationStructure();
|
||||||
void CreateShaders();
|
void CreateShaders();
|
||||||
void CreatePipeline();
|
void CreatePipeline();
|
||||||
void CreateFrameBuffer();
|
|
||||||
void CreateDescriptorSet();
|
void CreateDescriptorSet();
|
||||||
|
|
||||||
|
LightmapImage CreateImage(int width, int height);
|
||||||
|
|
||||||
void BeginCommands();
|
void BeginCommands();
|
||||||
void FinishCommands();
|
void FinishCommands();
|
||||||
|
|
||||||
|
@ -108,10 +125,6 @@ private:
|
||||||
std::unique_ptr<VulkanPipeline> pipeline;
|
std::unique_ptr<VulkanPipeline> pipeline;
|
||||||
std::unique_ptr<VulkanRenderPass> renderPass;
|
std::unique_ptr<VulkanRenderPass> renderPass;
|
||||||
|
|
||||||
std::unique_ptr<VulkanImage> framebufferImage;
|
|
||||||
std::unique_ptr<VulkanImageView> framebufferImageView;
|
|
||||||
std::unique_ptr<VulkanFramebuffer> framebuffer;
|
|
||||||
|
|
||||||
std::unique_ptr<VulkanBuffer> uniformBuffer;
|
std::unique_ptr<VulkanBuffer> uniformBuffer;
|
||||||
std::unique_ptr<VulkanBuffer> uniformTransferBuffer;
|
std::unique_ptr<VulkanBuffer> uniformTransferBuffer;
|
||||||
|
|
||||||
|
|
|
@ -192,7 +192,7 @@ std::unique_ptr<VulkanShader> ShaderBuilder::Create(const char *shadername, Vulk
|
||||||
bool compileSuccess = shader.parse(&resources, 110, false, EShMsgVulkanRules);
|
bool compileSuccess = shader.parse(&resources, 110, false, EShMsgVulkanRules);
|
||||||
if (!compileSuccess)
|
if (!compileSuccess)
|
||||||
{
|
{
|
||||||
throw std::runtime_error(std::string("Shader compile failed: ") + shader.getInfoLog());
|
throw std::runtime_error(std::string("Could not compile shader ") + shadername + ": " + shader.getInfoLog());
|
||||||
}
|
}
|
||||||
|
|
||||||
glslang::TProgram program;
|
glslang::TProgram program;
|
||||||
|
@ -200,7 +200,7 @@ std::unique_ptr<VulkanShader> ShaderBuilder::Create(const char *shadername, Vulk
|
||||||
bool linkSuccess = program.link(EShMsgDefault);
|
bool linkSuccess = program.link(EShMsgDefault);
|
||||||
if (!linkSuccess)
|
if (!linkSuccess)
|
||||||
{
|
{
|
||||||
throw std::runtime_error(std::string("Shader link failed: ") + program.getInfoLog());
|
throw std::runtime_error(std::string("Could not link shader ") + shadername + ": " + program.getInfoLog());
|
||||||
}
|
}
|
||||||
|
|
||||||
glslang::TIntermediate *intermediate = program.getIntermediate(stage);
|
glslang::TIntermediate *intermediate = program.getIntermediate(stage);
|
||||||
|
|
|
@ -200,9 +200,13 @@ void VulkanDevice::createDevice()
|
||||||
queueCreateInfos.push_back(queueCreateInfo);
|
queueCreateInfos.push_back(queueCreateInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VkPhysicalDeviceRayQueryFeaturesKHR rayqueryFeatures = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_QUERY_FEATURES_KHR };
|
||||||
|
rayqueryFeatures.rayQuery = true;
|
||||||
|
|
||||||
VkPhysicalDeviceRayTracingPipelineFeaturesKHR raytracingFeatures = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_PIPELINE_FEATURES_KHR };
|
VkPhysicalDeviceRayTracingPipelineFeaturesKHR raytracingFeatures = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_PIPELINE_FEATURES_KHR };
|
||||||
raytracingFeatures.rayTracingPipeline = true;
|
raytracingFeatures.rayTracingPipeline = true;
|
||||||
raytracingFeatures.rayTraversalPrimitiveCulling = true;
|
raytracingFeatures.rayTraversalPrimitiveCulling = true;
|
||||||
|
raytracingFeatures.pNext = &rayqueryFeatures;
|
||||||
|
|
||||||
VkPhysicalDeviceAccelerationStructureFeaturesKHR deviceAccelFeatures = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ACCELERATION_STRUCTURE_FEATURES_KHR };
|
VkPhysicalDeviceAccelerationStructureFeaturesKHR deviceAccelFeatures = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ACCELERATION_STRUCTURE_FEATURES_KHR };
|
||||||
deviceAccelFeatures.accelerationStructure = true;
|
deviceAccelFeatures.accelerationStructure = true;
|
||||||
|
|
|
@ -74,7 +74,7 @@ public:
|
||||||
VkPhysicalDeviceFeatures enabledDeviceFeatures = {};
|
VkPhysicalDeviceFeatures enabledDeviceFeatures = {};
|
||||||
std::vector<const char *> enabledDeviceExtensions = {
|
std::vector<const char *> enabledDeviceExtensions = {
|
||||||
//VK_KHR_SWAPCHAIN_EXTENSION_NAME,
|
//VK_KHR_SWAPCHAIN_EXTENSION_NAME,
|
||||||
//VK_KHR_RAY_QUERY_EXTENSION_NAME,
|
VK_KHR_RAY_QUERY_EXTENSION_NAME,
|
||||||
VK_KHR_RAY_TRACING_PIPELINE_EXTENSION_NAME,
|
VK_KHR_RAY_TRACING_PIPELINE_EXTENSION_NAME,
|
||||||
VK_KHR_ACCELERATION_STRUCTURE_EXTENSION_NAME,
|
VK_KHR_ACCELERATION_STRUCTURE_EXTENSION_NAME,
|
||||||
VK_KHR_DEFERRED_HOST_OPERATIONS_EXTENSION_NAME
|
VK_KHR_DEFERRED_HOST_OPERATIONS_EXTENSION_NAME
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
|
|
||||||
class VulkanCommandPool;
|
class VulkanCommandPool;
|
||||||
class VulkanDescriptorPool;
|
class VulkanDescriptorPool;
|
||||||
|
class VulkanCommandBuffer;
|
||||||
|
|
||||||
class VulkanSemaphore
|
class VulkanSemaphore
|
||||||
{
|
{
|
||||||
|
@ -307,13 +308,15 @@ class RenderPassBegin
|
||||||
public:
|
public:
|
||||||
RenderPassBegin();
|
RenderPassBegin();
|
||||||
|
|
||||||
void setRenderPass(VulkanRenderPass *renderpass);
|
RenderPassBegin& RenderPass(VulkanRenderPass *renderpass);
|
||||||
void setRenderArea(int x, int y, int width, int height);
|
RenderPassBegin& RenderArea(int x, int y, int width, int height);
|
||||||
void setFramebuffer(VulkanFramebuffer *framebuffer);
|
RenderPassBegin& Framebuffer(VulkanFramebuffer *framebuffer);
|
||||||
void addClearColor(float r, float g, float b, float a);
|
RenderPassBegin& AddClearColor(float r, float g, float b, float a);
|
||||||
void addClearDepth(float value);
|
RenderPassBegin& AddClearDepth(float value);
|
||||||
void addClearStencil(int value);
|
RenderPassBegin& AddClearStencil(int value);
|
||||||
void addClearDepthStencil(float depthValue, int stencilValue);
|
RenderPassBegin& AddClearDepthStencil(float depthValue, int stencilValue);
|
||||||
|
|
||||||
|
void Execute(VulkanCommandBuffer* cmdbuffer, VkSubpassContents contents = VK_SUBPASS_CONTENTS_INLINE);
|
||||||
|
|
||||||
VkRenderPassBeginInfo renderPassInfo = {};
|
VkRenderPassBeginInfo renderPassInfo = {};
|
||||||
|
|
||||||
|
@ -381,7 +384,6 @@ public:
|
||||||
void copyQueryPoolResults(VkQueryPool queryPool, uint32_t firstQuery, uint32_t queryCount, VkBuffer dstBuffer, VkDeviceSize dstOffset, VkDeviceSize stride, VkQueryResultFlags flags);
|
void copyQueryPoolResults(VkQueryPool queryPool, uint32_t firstQuery, uint32_t queryCount, VkBuffer dstBuffer, VkDeviceSize dstOffset, VkDeviceSize stride, VkQueryResultFlags flags);
|
||||||
void pushConstants(VulkanPipelineLayout *layout, VkShaderStageFlags stageFlags, uint32_t offset, uint32_t size, const void* pValues);
|
void pushConstants(VulkanPipelineLayout *layout, VkShaderStageFlags stageFlags, uint32_t offset, uint32_t size, const void* pValues);
|
||||||
void pushConstants(VkPipelineLayout layout, VkShaderStageFlags stageFlags, uint32_t offset, uint32_t size, const void* pValues);
|
void pushConstants(VkPipelineLayout layout, VkShaderStageFlags stageFlags, uint32_t offset, uint32_t size, const void* pValues);
|
||||||
void beginRenderPass(const RenderPassBegin &renderPassBegin, VkSubpassContents contents = VK_SUBPASS_CONTENTS_INLINE);
|
|
||||||
void beginRenderPass(const VkRenderPassBeginInfo* pRenderPassBegin, VkSubpassContents contents);
|
void beginRenderPass(const VkRenderPassBeginInfo* pRenderPassBegin, VkSubpassContents contents);
|
||||||
void nextSubpass(VkSubpassContents contents);
|
void nextSubpass(VkSubpassContents contents);
|
||||||
void endRenderPass();
|
void endRenderPass();
|
||||||
|
@ -509,25 +511,28 @@ inline RenderPassBegin::RenderPassBegin()
|
||||||
renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
|
renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void RenderPassBegin::setRenderPass(VulkanRenderPass *renderPass)
|
inline RenderPassBegin& RenderPassBegin::RenderPass(VulkanRenderPass *renderPass)
|
||||||
{
|
{
|
||||||
renderPassInfo.renderPass = renderPass->renderPass;
|
renderPassInfo.renderPass = renderPass->renderPass;
|
||||||
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void RenderPassBegin::setRenderArea(int x, int y, int width, int height)
|
inline RenderPassBegin& RenderPassBegin::RenderArea(int x, int y, int width, int height)
|
||||||
{
|
{
|
||||||
renderPassInfo.renderArea.offset.x = x;
|
renderPassInfo.renderArea.offset.x = x;
|
||||||
renderPassInfo.renderArea.offset.y = y;
|
renderPassInfo.renderArea.offset.y = y;
|
||||||
renderPassInfo.renderArea.extent.width = width;
|
renderPassInfo.renderArea.extent.width = width;
|
||||||
renderPassInfo.renderArea.extent.height = height;
|
renderPassInfo.renderArea.extent.height = height;
|
||||||
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void RenderPassBegin::setFramebuffer(VulkanFramebuffer *framebuffer)
|
inline RenderPassBegin& RenderPassBegin::Framebuffer(VulkanFramebuffer *framebuffer)
|
||||||
{
|
{
|
||||||
renderPassInfo.framebuffer = framebuffer->framebuffer;
|
renderPassInfo.framebuffer = framebuffer->framebuffer;
|
||||||
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void RenderPassBegin::addClearColor(float r, float g, float b, float a)
|
inline RenderPassBegin& RenderPassBegin::AddClearColor(float r, float g, float b, float a)
|
||||||
{
|
{
|
||||||
VkClearValue clearValue = { };
|
VkClearValue clearValue = { };
|
||||||
clearValue.color = { r, g, b, a };
|
clearValue.color = { r, g, b, a };
|
||||||
|
@ -535,9 +540,10 @@ inline void RenderPassBegin::addClearColor(float r, float g, float b, float a)
|
||||||
|
|
||||||
renderPassInfo.clearValueCount = (uint32_t)clearValues.size();
|
renderPassInfo.clearValueCount = (uint32_t)clearValues.size();
|
||||||
renderPassInfo.pClearValues = clearValues.data();
|
renderPassInfo.pClearValues = clearValues.data();
|
||||||
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void RenderPassBegin::addClearDepth(float value)
|
inline RenderPassBegin& RenderPassBegin::AddClearDepth(float value)
|
||||||
{
|
{
|
||||||
VkClearValue clearValue = { };
|
VkClearValue clearValue = { };
|
||||||
clearValue.depthStencil.depth = value;
|
clearValue.depthStencil.depth = value;
|
||||||
|
@ -545,9 +551,10 @@ inline void RenderPassBegin::addClearDepth(float value)
|
||||||
|
|
||||||
renderPassInfo.clearValueCount = (uint32_t)clearValues.size();
|
renderPassInfo.clearValueCount = (uint32_t)clearValues.size();
|
||||||
renderPassInfo.pClearValues = clearValues.data();
|
renderPassInfo.pClearValues = clearValues.data();
|
||||||
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void RenderPassBegin::addClearStencil(int value)
|
inline RenderPassBegin& RenderPassBegin::AddClearStencil(int value)
|
||||||
{
|
{
|
||||||
VkClearValue clearValue = { };
|
VkClearValue clearValue = { };
|
||||||
clearValue.depthStencil.stencil = value;
|
clearValue.depthStencil.stencil = value;
|
||||||
|
@ -555,9 +562,10 @@ inline void RenderPassBegin::addClearStencil(int value)
|
||||||
|
|
||||||
renderPassInfo.clearValueCount = (uint32_t)clearValues.size();
|
renderPassInfo.clearValueCount = (uint32_t)clearValues.size();
|
||||||
renderPassInfo.pClearValues = clearValues.data();
|
renderPassInfo.pClearValues = clearValues.data();
|
||||||
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void RenderPassBegin::addClearDepthStencil(float depthValue, int stencilValue)
|
inline RenderPassBegin& RenderPassBegin::AddClearDepthStencil(float depthValue, int stencilValue)
|
||||||
{
|
{
|
||||||
VkClearValue clearValue = { };
|
VkClearValue clearValue = { };
|
||||||
clearValue.depthStencil.depth = depthValue;
|
clearValue.depthStencil.depth = depthValue;
|
||||||
|
@ -566,6 +574,12 @@ inline void RenderPassBegin::addClearDepthStencil(float depthValue, int stencilV
|
||||||
|
|
||||||
renderPassInfo.clearValueCount = (uint32_t)clearValues.size();
|
renderPassInfo.clearValueCount = (uint32_t)clearValues.size();
|
||||||
renderPassInfo.pClearValues = clearValues.data();
|
renderPassInfo.pClearValues = clearValues.data();
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void RenderPassBegin::Execute(VulkanCommandBuffer* cmdbuffer, VkSubpassContents contents)
|
||||||
|
{
|
||||||
|
cmdbuffer->beginRenderPass(&renderPassInfo, contents);
|
||||||
}
|
}
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -896,11 +910,6 @@ inline void VulkanCommandBuffer::pushConstants(VkPipelineLayout layout, VkShader
|
||||||
vkCmdPushConstants(buffer, layout, stageFlags, offset, size, pValues);
|
vkCmdPushConstants(buffer, layout, stageFlags, offset, size, pValues);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void VulkanCommandBuffer::beginRenderPass(const RenderPassBegin &renderPassBegin, VkSubpassContents contents)
|
|
||||||
{
|
|
||||||
beginRenderPass(&renderPassBegin.renderPassInfo, contents);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void VulkanCommandBuffer::beginRenderPass(const VkRenderPassBeginInfo* pRenderPassBegin, VkSubpassContents contents)
|
inline void VulkanCommandBuffer::beginRenderPass(const VkRenderPassBeginInfo* pRenderPassBegin, VkSubpassContents contents)
|
||||||
{
|
{
|
||||||
vkCmdBeginRenderPass(buffer, pRenderPassBegin, contents);
|
vkCmdBeginRenderPass(buffer, pRenderPassBegin, contents);
|
||||||
|
|
Loading…
Reference in a new issue