Draw depth pass and portal occlusion test
This commit is contained in:
parent
04493ade52
commit
57fe68c8a1
6 changed files with 71 additions and 14 deletions
|
|
@ -268,6 +268,7 @@ public:
|
|||
std::unique_ptr<TriangleMeshShape> Collision;
|
||||
|
||||
TArray<LevelSubmeshDrawRange> DrawList;
|
||||
TArray<LevelSubmeshDrawRange> PortalList;
|
||||
|
||||
// Lightmap atlas
|
||||
int LMTextureCount = 0;
|
||||
|
|
|
|||
|
|
@ -240,7 +240,8 @@ std::unique_ptr<VulkanPipeline> VkRenderPassSetup::CreatePipeline(const VkPipeli
|
|||
|
||||
VkShaderProgram *program = fb->GetShaderManager()->Get(key.ShaderKey);
|
||||
builder.AddVertexShader(program->vert.get());
|
||||
builder.AddFragmentShader(program->frag.get());
|
||||
if (program->frag)
|
||||
builder.AddFragmentShader(program->frag.get());
|
||||
|
||||
const VkVertexFormat &vfmt = *fb->GetRenderPassManager()->GetVertexFormat(key.VertexFormat);
|
||||
|
||||
|
|
|
|||
|
|
@ -75,7 +75,8 @@ VkShaderProgram* VkShaderManager::Get(const VkShaderKey& key)
|
|||
|
||||
const auto& desc = effectshaders[key.SpecialEffect];
|
||||
program.vert = LoadVertShader(desc.ShaderName, mainvp, desc.defines, key.UseLevelMesh);
|
||||
program.frag = LoadFragShader(desc.ShaderName, desc.fp1, desc.fp2, desc.fp3, desc.fp4, desc.defines, key);
|
||||
if (!key.NoFragmentShader)
|
||||
program.frag = LoadFragShader(desc.ShaderName, desc.fp1, desc.fp2, desc.fp3, desc.fp4, desc.defines, key);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -113,7 +114,8 @@ VkShaderProgram* VkShaderManager::Get(const VkShaderKey& key)
|
|||
{
|
||||
const auto& desc = defaultshaders[key.EffectState];
|
||||
program.vert = LoadVertShader(desc.ShaderName, mainvp, desc.Defines, key.UseLevelMesh);
|
||||
program.frag = LoadFragShader(desc.ShaderName, mainfp, desc.material_lump, desc.mateffect_lump, desc.lightmodel_lump, desc.Defines, key);
|
||||
if (!key.NoFragmentShader)
|
||||
program.frag = LoadFragShader(desc.ShaderName, mainfp, desc.material_lump, desc.mateffect_lump, desc.lightmodel_lump, desc.Defines, key);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -122,7 +124,8 @@ VkShaderProgram* VkShaderManager::Get(const VkShaderKey& key)
|
|||
FString defines = defaultshaders[desc.shaderType].Defines + desc.defines;
|
||||
|
||||
program.vert = LoadVertShader(name, mainvp, defines.GetChars(), key.UseLevelMesh);
|
||||
program.frag = LoadFragShader(name, mainfp, desc.shader.GetChars(), defaultshaders[desc.shaderType].mateffect_lump, defaultshaders[desc.shaderType].lightmodel_lump, defines.GetChars(), key);
|
||||
if (!key.NoFragmentShader)
|
||||
program.frag = LoadFragShader(name, mainfp, desc.shader.GetChars(), defaultshaders[desc.shaderType].mateffect_lump, defaultshaders[desc.shaderType].lightmodel_lump, defines.GetChars(), key);
|
||||
}
|
||||
}
|
||||
return &program;
|
||||
|
|
|
|||
|
|
@ -80,7 +80,8 @@ public:
|
|||
uint64_t LightMode : 2; // LIGHTMODE_DEFAULT, LIGHTMODE_SOFTWARE, LIGHTMODE_VANILLA, LIGHTMODE_BUILD
|
||||
uint64_t UseLevelMesh : 1; // USE_LEVELMESH
|
||||
uint64_t FogBalls : 1; // FOGBALLS
|
||||
uint64_t Unused : 43;
|
||||
uint64_t NoFragmentShader : 1;
|
||||
uint64_t Unused : 42;
|
||||
};
|
||||
uint64_t AsQWORD = 0;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -789,25 +789,72 @@ void VulkanRenderDevice::DrawLevelMesh(const HWViewpointUniforms& viewpoint)
|
|||
matrices.TextureMatrix.loadIdentity();
|
||||
rsbuffers->MatrixBuffer->Write(matrices);
|
||||
|
||||
PushConstants pushConstants = {};
|
||||
pushConstants.uDataIndex = 0;
|
||||
pushConstants.uLightIndex = -1;
|
||||
pushConstants.uBoneIndexBase = -1;
|
||||
|
||||
auto submesh = GetRaytrace()->GetMesh()->StaticMesh.get();
|
||||
|
||||
// Draw opaque scene into the depth buffer
|
||||
for (LevelSubmeshDrawRange& range : submesh->DrawList)
|
||||
{
|
||||
auto& pipelineKey = levelMeshPipelineKeys[range.PipelineID];
|
||||
VulkanPipelineLayout* layout = GetRenderPassManager()->GetPipelineLayout(pipelineKey.NumTextureLayers, pipelineKey.ShaderKey.UseLevelMesh);
|
||||
cmdbuffer->bindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, passSetup->GetPipeline(pipelineKey));
|
||||
VkPipelineKey pipelineKey = levelMeshPipelineKeys[range.PipelineID];
|
||||
if (pipelineKey.ShaderKey.AlphaTest)
|
||||
continue;
|
||||
|
||||
pipelineKey.ShaderKey.NoFragmentShader = true;
|
||||
|
||||
VulkanPipelineLayout* layout = GetRenderPassManager()->GetPipelineLayout(pipelineKey.NumTextureLayers, pipelineKey.ShaderKey.UseLevelMesh);
|
||||
uint32_t viewpointOffset = viewpointIndex * rsbuffers->Viewpoint.BlockAlign;
|
||||
uint32_t matrixOffset = rsbuffers->MatrixBuffer->Offset();
|
||||
uint32_t lightsOffset = 0;
|
||||
uint32_t offsets[] = { viewpointOffset, matrixOffset, lightsOffset };
|
||||
cmdbuffer->bindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, passSetup->GetPipeline(pipelineKey));
|
||||
cmdbuffer->bindDescriptorSet(VK_PIPELINE_BIND_POINT_GRAPHICS, layout, 0, descriptors->GetFixedSet());
|
||||
cmdbuffer->bindDescriptorSet(VK_PIPELINE_BIND_POINT_GRAPHICS, layout, 1, descriptors->GetLevelMeshSet(), 3, offsets);
|
||||
cmdbuffer->bindDescriptorSet(VK_PIPELINE_BIND_POINT_GRAPHICS, layout, 2, descriptors->GetBindlessSet());
|
||||
cmdbuffer->pushConstants(layout, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, 0, (uint32_t)sizeof(PushConstants), &pushConstants);
|
||||
|
||||
PushConstants pushConstants = {};
|
||||
pushConstants.uDataIndex = 0;
|
||||
pushConstants.uLightIndex = -1;
|
||||
pushConstants.uBoneIndexBase = -1;
|
||||
cmdbuffer->drawIndexed(range.Count, 1, range.Start, 0, 0);
|
||||
}
|
||||
|
||||
// Draw portal surface occlusion queries
|
||||
|
||||
for (LevelSubmeshDrawRange& range : submesh->PortalList)
|
||||
{
|
||||
VkPipelineKey pipelineKey = levelMeshPipelineKeys[range.PipelineID];
|
||||
pipelineKey.ShaderKey.NoFragmentShader = true;
|
||||
|
||||
VulkanPipelineLayout* layout = GetRenderPassManager()->GetPipelineLayout(pipelineKey.NumTextureLayers, pipelineKey.ShaderKey.UseLevelMesh);
|
||||
uint32_t viewpointOffset = viewpointIndex * rsbuffers->Viewpoint.BlockAlign;
|
||||
uint32_t matrixOffset = rsbuffers->MatrixBuffer->Offset();
|
||||
uint32_t lightsOffset = 0;
|
||||
uint32_t offsets[] = { viewpointOffset, matrixOffset, lightsOffset };
|
||||
cmdbuffer->bindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, passSetup->GetPipeline(pipelineKey));
|
||||
cmdbuffer->bindDescriptorSet(VK_PIPELINE_BIND_POINT_GRAPHICS, layout, 0, descriptors->GetFixedSet());
|
||||
cmdbuffer->bindDescriptorSet(VK_PIPELINE_BIND_POINT_GRAPHICS, layout, 1, descriptors->GetLevelMeshSet(), 3, offsets);
|
||||
cmdbuffer->bindDescriptorSet(VK_PIPELINE_BIND_POINT_GRAPHICS, layout, 2, descriptors->GetBindlessSet());
|
||||
cmdbuffer->pushConstants(layout, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, 0, (uint32_t)sizeof(PushConstants), &pushConstants);
|
||||
|
||||
// To do: add occlusion query
|
||||
|
||||
cmdbuffer->drawIndexed(range.Count, 1, range.Start, 0, 0);
|
||||
}
|
||||
|
||||
// Draw opaque scene
|
||||
for (LevelSubmeshDrawRange& range : submesh->DrawList)
|
||||
{
|
||||
auto& pipelineKey = levelMeshPipelineKeys[range.PipelineID];
|
||||
VulkanPipelineLayout* layout = GetRenderPassManager()->GetPipelineLayout(pipelineKey.NumTextureLayers, pipelineKey.ShaderKey.UseLevelMesh);
|
||||
uint32_t viewpointOffset = viewpointIndex * rsbuffers->Viewpoint.BlockAlign;
|
||||
uint32_t matrixOffset = rsbuffers->MatrixBuffer->Offset();
|
||||
uint32_t lightsOffset = 0;
|
||||
uint32_t offsets[] = { viewpointOffset, matrixOffset, lightsOffset };
|
||||
cmdbuffer->bindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, passSetup->GetPipeline(pipelineKey));
|
||||
cmdbuffer->bindDescriptorSet(VK_PIPELINE_BIND_POINT_GRAPHICS, layout, 0, descriptors->GetFixedSet());
|
||||
cmdbuffer->bindDescriptorSet(VK_PIPELINE_BIND_POINT_GRAPHICS, layout, 1, descriptors->GetLevelMeshSet(), 3, offsets);
|
||||
cmdbuffer->bindDescriptorSet(VK_PIPELINE_BIND_POINT_GRAPHICS, layout, 2, descriptors->GetBindlessSet());
|
||||
cmdbuffer->pushConstants(layout, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, 0, (uint32_t)sizeof(PushConstants), &pushConstants);
|
||||
|
||||
cmdbuffer->drawIndexed(range.Count, 1, range.Start, 0, 0);
|
||||
|
|
|
|||
|
|
@ -217,17 +217,17 @@ void DoomLevelSubmesh::CreateDynamicSurfaces(FLevelLocals& doomMap)
|
|||
void DoomLevelSubmesh::CreateIndexes()
|
||||
{
|
||||
// Order indexes by pipeline
|
||||
std::unordered_map<int, TArray<int>> pipelineSurfaces;
|
||||
std::unordered_map<int64_t, TArray<int>> pipelineSurfaces;
|
||||
for (size_t i = 0; i < Surfaces.Size(); i++)
|
||||
{
|
||||
DoomLevelMeshSurface* s = &Surfaces[i];
|
||||
pipelineSurfaces[s->PipelineID].Push(i);
|
||||
pipelineSurfaces[(int64_t(s->PipelineID) << 32) | int64_t(s->bSky)].Push(i);
|
||||
}
|
||||
|
||||
for (const auto& it : pipelineSurfaces)
|
||||
{
|
||||
LevelSubmeshDrawRange range;
|
||||
range.PipelineID = it.first;
|
||||
range.PipelineID = it.first >> 32;
|
||||
range.Start = MeshElements.Size();
|
||||
for (unsigned int i : it.second)
|
||||
{
|
||||
|
|
@ -289,7 +289,11 @@ void DoomLevelSubmesh::CreateIndexes()
|
|||
}
|
||||
}
|
||||
range.Count = MeshElements.Size() - range.Start;
|
||||
DrawList.Push(range);
|
||||
|
||||
if ((it.first & 1) == 0)
|
||||
DrawList.Push(range);
|
||||
else
|
||||
PortalList.Push(range);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue