mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-10 14:51:40 +00:00
Hook up the acceleration structure to the shader and start shooting some rays!
This commit is contained in:
parent
e08965b0b3
commit
0c1aab074c
6 changed files with 98 additions and 11 deletions
|
@ -33,18 +33,37 @@ void VkRaytrace::SetLevelMesh(hwrenderer::LevelMesh* mesh)
|
|||
Mesh = mesh;
|
||||
if (Mesh)
|
||||
{
|
||||
if (GetVulkanFrameBuffer()->device->SupportsDeviceExtension(VK_KHR_ACCELERATION_STRUCTURE_EXTENSION_NAME) && GetVulkanFrameBuffer()->device->SupportsDeviceExtension(VK_KHR_DEFERRED_HOST_OPERATIONS_EXTENSION_NAME))
|
||||
if (GetVulkanFrameBuffer()->device->SupportsDeviceExtension(VK_KHR_RAY_QUERY_EXTENSION_NAME))
|
||||
{
|
||||
CreateVulkanObjects();
|
||||
}
|
||||
else
|
||||
{
|
||||
Printf("This vulkan device does not support ray tracing.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
VulkanAccelerationStructure* VkRaytrace::GetAccelStruct()
|
||||
{
|
||||
if (tlAccelStruct)
|
||||
return tlAccelStruct.get();
|
||||
|
||||
// We need a dummy accel struct to keep vulkan happy:
|
||||
hwrenderer::LevelMesh dummy;
|
||||
dummy.MeshVertices.Push({ 0.0f, 0.0f, 0.0f });
|
||||
dummy.MeshVertices.Push({ 0.0f, 1.0f, 0.0f });
|
||||
dummy.MeshVertices.Push({ 1.0f, 0.0f, 0.0f });
|
||||
dummy.MeshUVIndex.Push(0);
|
||||
dummy.MeshUVIndex.Push(1);
|
||||
dummy.MeshUVIndex.Push(2);
|
||||
dummy.MeshElements.Push(0);
|
||||
dummy.MeshElements.Push(1);
|
||||
dummy.MeshElements.Push(2);
|
||||
dummy.MeshSurfaces.Push(0);
|
||||
Mesh = &dummy;
|
||||
CreateVulkanObjects();
|
||||
Mesh = nullptr;
|
||||
return tlAccelStruct.get();
|
||||
}
|
||||
|
||||
void VkRaytrace::Reset()
|
||||
{
|
||||
vertexBuffer.reset();
|
||||
|
@ -73,8 +92,8 @@ void VkRaytrace::CreateVulkanObjects()
|
|||
//CreateDescriptorSet();
|
||||
|
||||
PipelineBarrier finishbuildbarrier;
|
||||
finishbuildbarrier.addMemory(VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR, VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR);
|
||||
finishbuildbarrier.execute(GetVulkanFrameBuffer()->GetTransferCommands(), VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR, VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR);
|
||||
finishbuildbarrier.addMemory(VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR, VK_ACCESS_SHADER_READ_BIT);
|
||||
finishbuildbarrier.execute(GetVulkanFrameBuffer()->GetTransferCommands(), VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
|
||||
}
|
||||
|
||||
void VkRaytrace::CreateVertexAndIndexBuffers()
|
||||
|
@ -107,8 +126,8 @@ void VkRaytrace::CreateVertexAndIndexBuffers()
|
|||
memcpy(data + indexoffset, Mesh->MeshElements.Data(), indexbuffersize);
|
||||
transferBuffer->Unmap();
|
||||
|
||||
GetVulkanFrameBuffer()->GetTransferCommands()->copyBuffer(transferBuffer.get(), vertexBuffer.get(), vertexoffset);
|
||||
GetVulkanFrameBuffer()->GetTransferCommands()->copyBuffer(transferBuffer.get(), indexBuffer.get(), indexoffset);
|
||||
GetVulkanFrameBuffer()->GetTransferCommands()->copyBuffer(transferBuffer.get(), vertexBuffer.get(), vertexoffset, 0, vertexbuffersize);
|
||||
GetVulkanFrameBuffer()->GetTransferCommands()->copyBuffer(transferBuffer.get(), indexBuffer.get(), indexoffset, 0, indexbuffersize);
|
||||
|
||||
VkMemoryBarrier barrier = { VK_STRUCTURE_TYPE_MEMORY_BARRIER };
|
||||
barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
|
||||
|
|
|
@ -9,6 +9,8 @@ class VkRaytrace
|
|||
public:
|
||||
void SetLevelMesh(hwrenderer::LevelMesh* mesh);
|
||||
|
||||
VulkanAccelerationStructure* GetAccelStruct();
|
||||
|
||||
private:
|
||||
void Reset();
|
||||
void CreateVulkanObjects();
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include "vk_renderpass.h"
|
||||
#include "vk_renderbuffers.h"
|
||||
#include "vk_renderstate.h"
|
||||
#include "vk_raytrace.h"
|
||||
#include "vulkan/textures/vk_samplers.h"
|
||||
#include "vulkan/shaders/vk_shader.h"
|
||||
#include "vulkan/system/vk_builders.h"
|
||||
|
@ -131,6 +132,8 @@ void VkRenderPassManager::CreateDynamicSetLayout()
|
|||
builder.addBinding(3, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 1, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT);
|
||||
builder.addBinding(4, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT);
|
||||
builder.addBinding(5, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT);
|
||||
if (GetVulkanFrameBuffer()->device->SupportsDeviceExtension(VK_KHR_RAY_QUERY_EXTENSION_NAME))
|
||||
builder.addBinding(6, VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, 1, VK_SHADER_STAGE_FRAGMENT_BIT);
|
||||
DynamicSetLayout = builder.create(GetVulkanFrameBuffer()->device);
|
||||
DynamicSetLayout->SetDebugName("VkRenderPassManager.DynamicSetLayout");
|
||||
}
|
||||
|
@ -179,6 +182,8 @@ void VkRenderPassManager::CreateDescriptorPool()
|
|||
builder.addPoolSize(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 3);
|
||||
builder.addPoolSize(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1);
|
||||
builder.addPoolSize(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 2);
|
||||
if (GetVulkanFrameBuffer()->device->SupportsDeviceExtension(VK_KHR_RAY_QUERY_EXTENSION_NAME))
|
||||
builder.addPoolSize(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, 1);
|
||||
builder.setMaxSets(1);
|
||||
DynamicDescriptorPool = builder.create(GetVulkanFrameBuffer()->device);
|
||||
DynamicDescriptorPool->SetDebugName("VkRenderPassManager.DynamicDescriptorPool");
|
||||
|
@ -251,6 +256,8 @@ void VkRenderPassManager::UpdateDynamicSet()
|
|||
update.addBuffer(DynamicSet.get(), 3, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, fb->StreamBuffer->UniformBuffer->mBuffer.get(), 0, sizeof(StreamUBO));
|
||||
update.addCombinedImageSampler(DynamicSet.get(), 4, fb->GetBuffers()->Shadowmap.View.get(), fb->GetBuffers()->ShadowmapSampler.get(), VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
|
||||
update.addCombinedImageSampler(DynamicSet.get(), 5, fb->GetBuffers()->Lightmap.View.get(), fb->GetBuffers()->LightmapSampler.get(), VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
|
||||
if (GetVulkanFrameBuffer()->device->SupportsDeviceExtension(VK_KHR_RAY_QUERY_EXTENSION_NAME))
|
||||
update.addAccelerationStructure(DynamicSet.get(), 6, fb->GetRaytrace()->GetAccelStruct());
|
||||
update.updateSets(fb->device);
|
||||
}
|
||||
|
||||
|
|
|
@ -216,6 +216,7 @@ static const char *shaderBindings = R"(
|
|||
|
||||
layout(set = 0, binding = 4) uniform sampler2D ShadowMap;
|
||||
layout(set = 0, binding = 5) uniform sampler2DArray LightMap;
|
||||
layout(set = 0, binding = 6) uniform accelerationStructureEXT TopLevelAS;
|
||||
|
||||
// textures
|
||||
layout(set = 1, binding = 0) uniform sampler2D tex;
|
||||
|
@ -337,6 +338,7 @@ std::unique_ptr<VulkanShader> VkShaderManager::LoadVertShader(FString shadername
|
|||
std::unique_ptr<VulkanShader> VkShaderManager::LoadFragShader(FString shadername, const char *frag_lump, const char *material_lump, const char *light_lump, const char *defines, bool alphatest, bool gbufferpass)
|
||||
{
|
||||
FString code = GetTargetGlslVersion();
|
||||
code << "\n#define SUPPORTS_RAYTRACING\n";
|
||||
code << defines;
|
||||
code << "\n$placeholder$"; // here the code can later add more needed #defines.
|
||||
code << "\n#define MAX_STREAM_DATA " << std::to_string(MAX_STREAM_DATA).c_str() << "\n";
|
||||
|
@ -425,7 +427,17 @@ std::unique_ptr<VulkanShader> VkShaderManager::LoadFragShader(FString shadername
|
|||
|
||||
FString VkShaderManager::GetTargetGlslVersion()
|
||||
{
|
||||
return "#version 450 core\n";
|
||||
if (device->ApiVersion == VK_API_VERSION_1_2)
|
||||
{
|
||||
return R"(#version 460
|
||||
#extension GL_EXT_ray_tracing : enable
|
||||
#extension GL_EXT_ray_query : enable
|
||||
)";
|
||||
}
|
||||
else
|
||||
{
|
||||
return "#version 450 core\n";
|
||||
}
|
||||
}
|
||||
|
||||
FString VkShaderManager::LoadPublicShaderLump(const char *lumpname)
|
||||
|
|
|
@ -345,6 +345,7 @@ public:
|
|||
void addBuffer(VulkanDescriptorSet *descriptorSet, int binding, VkDescriptorType type, VulkanBuffer *buffer, size_t offset, size_t range);
|
||||
void addStorageImage(VulkanDescriptorSet *descriptorSet, int binding, VulkanImageView *view, VkImageLayout imageLayout);
|
||||
void addCombinedImageSampler(VulkanDescriptorSet *descriptorSet, int binding, VulkanImageView *view, VulkanSampler *sampler, VkImageLayout imageLayout);
|
||||
void addAccelerationStructure(VulkanDescriptorSet* descriptorSet, int binding, VulkanAccelerationStructure* accelStruct);
|
||||
|
||||
void updateSets(VulkanDevice *device);
|
||||
|
||||
|
@ -354,6 +355,7 @@ private:
|
|||
VkDescriptorImageInfo imageInfo;
|
||||
VkDescriptorBufferInfo bufferInfo;
|
||||
VkBufferView bufferView;
|
||||
VkWriteDescriptorSetAccelerationStructureKHR accelStruct;
|
||||
};
|
||||
|
||||
std::vector<VkWriteDescriptorSet> writes;
|
||||
|
@ -1384,6 +1386,26 @@ inline void WriteDescriptors::addCombinedImageSampler(VulkanDescriptorSet *descr
|
|||
writeExtras.push_back(std::move(extra));
|
||||
}
|
||||
|
||||
inline void WriteDescriptors::addAccelerationStructure(VulkanDescriptorSet* descriptorSet, int binding, VulkanAccelerationStructure* accelStruct)
|
||||
{
|
||||
auto extra = std::make_unique<WriteExtra>();
|
||||
extra->accelStruct = {};
|
||||
extra->accelStruct.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_KHR;
|
||||
extra->accelStruct.accelerationStructureCount = 1;
|
||||
extra->accelStruct.pAccelerationStructures = &accelStruct->accelstruct;
|
||||
|
||||
VkWriteDescriptorSet descriptorWrite = {};
|
||||
descriptorWrite.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
|
||||
descriptorWrite.dstSet = descriptorSet->set;
|
||||
descriptorWrite.dstBinding = binding;
|
||||
descriptorWrite.dstArrayElement = 0;
|
||||
descriptorWrite.descriptorType = VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR;
|
||||
descriptorWrite.descriptorCount = 1;
|
||||
descriptorWrite.pNext = &extra->accelStruct;
|
||||
writes.push_back(descriptorWrite);
|
||||
writeExtras.push_back(std::move(extra));
|
||||
}
|
||||
|
||||
inline void WriteDescriptors::updateSets(VulkanDevice *device)
|
||||
{
|
||||
vkUpdateDescriptorSets(device->device, (uint32_t)writes.size(), writes.data(), 0, nullptr);
|
||||
|
|
|
@ -341,10 +341,34 @@ float R_DoomLightingEquation(float light)
|
|||
|
||||
//===========================================================================
|
||||
//
|
||||
// Check if light is in shadow according to its 1D shadow map
|
||||
// Check if light is in shadow
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
#ifdef SUPPORTS_RAYTRACING
|
||||
|
||||
float shadowAttenuation(vec4 lightpos, float lightcolorA)
|
||||
{
|
||||
vec3 origin = pixelpos.xyz;
|
||||
vec3 direction = normalize(lightpos.xyz - pixelpos.xyz);
|
||||
float lightDistance = distance(pixelpos.xyz, lightpos.xyz);
|
||||
|
||||
rayQueryEXT rayQuery;
|
||||
rayQueryInitializeEXT(rayQuery, TopLevelAS, gl_RayFlagsTerminateOnFirstHitEXT, 0xFF, origin, 0.01f, direction, lightDistance);
|
||||
|
||||
while(rayQueryProceedEXT(rayQuery))
|
||||
{
|
||||
}
|
||||
|
||||
if (rayQueryGetIntersectionTypeEXT(rayQuery, true) != gl_RayQueryCommittedIntersectionNoneEXT)
|
||||
{
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
return 1.0;
|
||||
}
|
||||
|
||||
#else
|
||||
#ifdef SUPPORTS_SHADOWMAPS
|
||||
|
||||
float shadowDirToU(vec2 dir)
|
||||
|
@ -488,6 +512,7 @@ float shadowAttenuation(vec4 lightpos, float lightcolorA)
|
|||
return 1.0;
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
float spotLightAttenuation(vec4 lightpos, vec3 spotdir, float lightCosInnerAngle, float lightCosOuterAngle)
|
||||
|
|
Loading…
Reference in a new issue