Move lightmap atlas textures and light probes to the bindless textures array as its impossible to predict up front how many we need
This commit is contained in:
parent
8d1a2c39f4
commit
af6ec929cc
19 changed files with 317 additions and 249 deletions
|
|
@ -200,7 +200,7 @@ public:
|
|||
// Lightmap tiles and their locations in the texture atlas
|
||||
struct
|
||||
{
|
||||
int TextureCount = 10; // To do: remove all the limits and instead resize GPU resources if they are exhausted. Too difficult to calculate it all up front.
|
||||
int TextureCount = 1;
|
||||
int TextureSize = 1024;
|
||||
TArray<uint16_t> TextureData;
|
||||
uint16_t SampleDistance = 8;
|
||||
|
|
|
|||
|
|
@ -150,6 +150,7 @@ protected:
|
|||
int mLightIndex;
|
||||
int mBoneIndexBase;
|
||||
int mFogballIndex;
|
||||
int mLightProbeIndex;
|
||||
int mSpecialEffect;
|
||||
int mTextureMode;
|
||||
int mTextureClamp;
|
||||
|
|
@ -217,7 +218,7 @@ public:
|
|||
mSurfaceUniforms.uFogDensity = 0.0f;
|
||||
mSurfaceUniforms.uLightLevel = -1.0f;
|
||||
mSurfaceUniforms.uDepthFadeThreshold = 0.0f;
|
||||
mSurfaceUniforms.uLightProbeIndex = 0;
|
||||
mLightProbeIndex = 0;
|
||||
mSpecialEffect = EFF_NONE;
|
||||
mLightIndex = -1;
|
||||
mBoneIndexBase = -1;
|
||||
|
|
@ -569,7 +570,7 @@ public:
|
|||
|
||||
void SetLightProbeIndex(int index)
|
||||
{
|
||||
mSurfaceUniforms.uLightProbeIndex = index;
|
||||
mLightProbeIndex = index;
|
||||
}
|
||||
|
||||
void SetRenderStyle(FRenderStyle rs)
|
||||
|
|
|
|||
|
|
@ -144,24 +144,21 @@ void VkDescriptorSetManager::UpdateFixedSet()
|
|||
|
||||
WriteDescriptors update;
|
||||
update.AddCombinedImageSampler(Fixed.Set.get(), 0, fb->GetTextureManager()->Shadowmap.View.get(), fb->GetSamplerManager()->ShadowmapSampler.get(), VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
|
||||
update.AddCombinedImageSampler(Fixed.Set.get(), 1, fb->GetTextureManager()->Lightmap.Image.View.get(), fb->GetSamplerManager()->LightmapSampler.get(), VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
|
||||
update.AddCombinedImageSampler(Fixed.Set.get(), 2, fb->GetBuffers()->SceneLinearDepth.View.get(), fb->GetSamplerManager()->Get(PPFilterMode::Nearest, PPWrapMode::Clamp), VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
|
||||
update.AddCombinedImageSampler(Fixed.Set.get(), 3, fb->GetTextureManager()->Irradiancemap.Image.View.get(), fb->GetSamplerManager()->IrradiancemapSampler.get(), VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
|
||||
update.AddCombinedImageSampler(Fixed.Set.get(), 4, fb->GetTextureManager()->Prefiltermap.Image.View.get(), fb->GetSamplerManager()->PrefiltermapSampler.get(), VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
|
||||
update.AddCombinedImageSampler(Fixed.Set.get(), 1, fb->GetBuffers()->SceneLinearDepth.View.get(), fb->GetSamplerManager()->Get(PPFilterMode::Nearest, PPWrapMode::Clamp), VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
|
||||
if (fb->IsRayQueryEnabled())
|
||||
{
|
||||
update.AddAccelerationStructure(Fixed.Set.get(), 5, fb->GetLevelMesh()->GetAccelStruct());
|
||||
update.AddAccelerationStructure(Fixed.Set.get(), 2, fb->GetLevelMesh()->GetAccelStruct());
|
||||
}
|
||||
else
|
||||
{
|
||||
update.AddBuffer(Fixed.Set.get(), 5, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, fb->GetLevelMesh()->GetNodeBuffer());
|
||||
update.AddBuffer(Fixed.Set.get(), 2, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, fb->GetLevelMesh()->GetNodeBuffer());
|
||||
}
|
||||
|
||||
update.AddBuffer(Fixed.Set.get(), 6, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, fb->GetLevelMesh()->GetVertexBuffer());
|
||||
update.AddBuffer(Fixed.Set.get(), 7, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, fb->GetLevelMesh()->GetIndexBuffer());
|
||||
update.AddBuffer(Fixed.Set.get(), 8, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, fb->GetLevelMesh()->GetSurfaceIndexBuffer());
|
||||
update.AddBuffer(Fixed.Set.get(), 9, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, fb->GetLevelMesh()->GetSurfaceBuffer());
|
||||
update.AddBuffer(Fixed.Set.get(), 10, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, fb->GetLevelMesh()->GetPortalBuffer());
|
||||
update.AddBuffer(Fixed.Set.get(), 3, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, fb->GetLevelMesh()->GetVertexBuffer());
|
||||
update.AddBuffer(Fixed.Set.get(), 4, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, fb->GetLevelMesh()->GetIndexBuffer());
|
||||
update.AddBuffer(Fixed.Set.get(), 5, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, fb->GetLevelMesh()->GetSurfaceIndexBuffer());
|
||||
update.AddBuffer(Fixed.Set.get(), 6, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, fb->GetLevelMesh()->GetSurfaceBuffer());
|
||||
update.AddBuffer(Fixed.Set.get(), 7, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, fb->GetLevelMesh()->GetPortalBuffer());
|
||||
|
||||
update.Execute(fb->GetDevice());
|
||||
}
|
||||
|
|
@ -175,6 +172,8 @@ void VkDescriptorSetManager::ResetHWTextureSets()
|
|||
colormap->Renderdev.bindIndex = -1;
|
||||
Colormaps.clear();
|
||||
|
||||
LightProbes.clear();
|
||||
|
||||
Bindless.Writer = WriteDescriptors();
|
||||
Bindless.NextIndex = 0;
|
||||
|
||||
|
|
@ -186,6 +185,9 @@ void VkDescriptorSetManager::ResetHWTextureSets()
|
|||
|
||||
// Slot 2 is always our game palette texture
|
||||
AddBindlessTextureIndex(fb->GetTextureManager()->GetGamePaletteView(), fb->GetSamplerManager()->Get(CLAMP_XY_NOMIP));
|
||||
|
||||
// Lightmap textures follow
|
||||
Bindless.NextIndex = LightmapsStart + MaxLightmaps;
|
||||
}
|
||||
|
||||
void VkDescriptorSetManager::AddMaterial(VkMaterial* texture)
|
||||
|
|
@ -286,22 +288,19 @@ void VkDescriptorSetManager::CreateFixedLayout()
|
|||
DescriptorSetLayoutBuilder builder;
|
||||
builder.AddBinding(0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT);
|
||||
builder.AddBinding(1, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT);
|
||||
builder.AddBinding(2, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT);
|
||||
builder.AddBinding(3, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT);
|
||||
builder.AddBinding(4, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT);
|
||||
if (fb->IsRayQueryEnabled())
|
||||
{
|
||||
builder.AddBinding(5, VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, 1, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT);
|
||||
builder.AddBinding(2, VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, 1, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT);
|
||||
}
|
||||
else
|
||||
{
|
||||
builder.AddBinding(5, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT);
|
||||
builder.AddBinding(2, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT);
|
||||
}
|
||||
builder.AddBinding(3, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT);
|
||||
builder.AddBinding(4, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT);
|
||||
builder.AddBinding(5, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT);
|
||||
builder.AddBinding(6, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT);
|
||||
builder.AddBinding(7, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT);
|
||||
builder.AddBinding(8, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT);
|
||||
builder.AddBinding(9, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT);
|
||||
builder.AddBinding(10, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT);
|
||||
builder.DebugName("VkDescriptorSetManager.Fixed.SetLayout");
|
||||
Fixed.Layout = builder.Create(fb->GetDevice());
|
||||
}
|
||||
|
|
@ -367,7 +366,7 @@ void VkDescriptorSetManager::CreateRSBufferPool()
|
|||
void VkDescriptorSetManager::CreateFixedPool()
|
||||
{
|
||||
DescriptorPoolBuilder poolbuilder;
|
||||
poolbuilder.AddPoolSize(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 5 * MaxFixedSets);
|
||||
poolbuilder.AddPoolSize(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 2 * MaxFixedSets);
|
||||
if (fb->IsRayQueryEnabled())
|
||||
{
|
||||
poolbuilder.AddPoolSize(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, 1 * MaxFixedSets);
|
||||
|
|
@ -406,6 +405,14 @@ void VkDescriptorSetManager::CreateBindlessSet()
|
|||
|
||||
void VkDescriptorSetManager::UpdateBindlessDescriptorSet()
|
||||
{
|
||||
auto sampler = fb->GetSamplerManager()->LightmapSampler.get();
|
||||
int index = LightmapsStart;
|
||||
for (auto& lightmap : fb->GetTextureManager()->Lightmaps)
|
||||
{
|
||||
Bindless.Writer.AddCombinedImageSampler(Bindless.Set.get(), 0, index, lightmap.View.get(), sampler, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
|
||||
index++;
|
||||
}
|
||||
|
||||
Bindless.Writer.Execute(fb->GetDevice());
|
||||
Bindless.Writer = WriteDescriptors();
|
||||
}
|
||||
|
|
@ -426,3 +433,17 @@ int VkDescriptorSetManager::GetSWColormapTextureIndex(FSWColormap* colormap)
|
|||
Colormaps.push_back(colormap);
|
||||
return colormap->Renderdev.bindIndex;
|
||||
}
|
||||
|
||||
int VkDescriptorSetManager::GetLightProbeTextureIndex(int probeIndex)
|
||||
{
|
||||
if ((size_t)probeIndex >= LightProbes.size())
|
||||
LightProbes.resize(probeIndex + 1, -1);
|
||||
|
||||
if (LightProbes[probeIndex] == -1)
|
||||
{
|
||||
LightProbes[probeIndex] = AddBindlessTextureIndex(fb->GetTextureManager()->Irradiancemaps[probeIndex].View.get(), fb->GetSamplerManager()->IrradiancemapSampler.get());
|
||||
AddBindlessTextureIndex(fb->GetTextureManager()->Prefiltermaps[probeIndex].View.get(), fb->GetSamplerManager()->PrefiltermapSampler.get());
|
||||
}
|
||||
|
||||
return LightProbes[probeIndex];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -46,6 +46,7 @@ public:
|
|||
int AddBindlessTextureIndex(VulkanImageView* imageview, VulkanSampler* sampler);
|
||||
|
||||
int GetSWColormapTextureIndex(FSWColormap* colormap);
|
||||
int GetLightProbeTextureIndex(int probeIndex);
|
||||
|
||||
private:
|
||||
void CreateLevelMeshLayout();
|
||||
|
|
@ -98,6 +99,13 @@ private:
|
|||
int NextIndex = 0;
|
||||
} Bindless;
|
||||
|
||||
struct
|
||||
{
|
||||
std::unique_ptr<VulkanDescriptorPool> Pool;
|
||||
std::unique_ptr<VulkanDescriptorSet> Set;
|
||||
std::unique_ptr<VulkanDescriptorSetLayout> Layout;
|
||||
} Lightmap;
|
||||
|
||||
struct
|
||||
{
|
||||
std::unique_ptr<VulkanDescriptorPool> Pool;
|
||||
|
|
@ -119,7 +127,10 @@ private:
|
|||
|
||||
std::list<VkMaterial*> Materials;
|
||||
std::vector<FSWColormap*> Colormaps;
|
||||
std::vector<int> LightProbes;
|
||||
|
||||
static const int MaxFixedSets = 100;
|
||||
static const int MaxBindlessTextures = 16536;
|
||||
static const int LightmapsStart = 3;
|
||||
static const int MaxLightmaps = 128;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -247,9 +247,10 @@ static std::vector<BuiltinFieldDesc> vertexShaderOutputs
|
|||
{"vEyeNormal", "", UniformType::Vec4, FieldCondition::ALWAYS}, //6
|
||||
{"ClipDistanceA", "", UniformType::Vec4, FieldCondition::HAS_CLIPDISTANCE}, //7
|
||||
{"ClipDistanceB", "", UniformType::Vec4, FieldCondition::HAS_CLIPDISTANCE}, //8
|
||||
{"vLightmap", "", UniformType::Vec3, FieldCondition::ALWAYS}, //9
|
||||
{"uDataIndex", "flat", UniformType::Int, FieldCondition::USELEVELMESH}, //10
|
||||
{"vLightColor", "", UniformType::Vec3, FieldCondition::SHADE_VERTEX}, //11
|
||||
{"vLightmap", "", UniformType::Vec2, FieldCondition::ALWAYS}, //9
|
||||
{"vLightmapIndex", "flat", UniformType::Int, FieldCondition::ALWAYS}, //10
|
||||
{"uDataIndex", "flat", UniformType::Int, FieldCondition::USELEVELMESH}, //11
|
||||
{"vLightColor", "", UniformType::Vec3, FieldCondition::SHADE_VERTEX}, //12
|
||||
};
|
||||
|
||||
static std::vector<BuiltinFieldDesc> fragShaderOutputs
|
||||
|
|
|
|||
|
|
@ -19,12 +19,8 @@ public:
|
|||
for (auto &it : RSFramebuffers)
|
||||
deletelist->Add(std::move(it.second));
|
||||
RSFramebuffers.clear();
|
||||
for (auto& framebuffer : LMFramebuffers)
|
||||
deletelist->Add(std::move(framebuffer));
|
||||
LMFramebuffers.clear();
|
||||
for (auto& view : LMViews)
|
||||
deletelist->Add(std::move(view));
|
||||
LMViews.clear();
|
||||
deletelist->Add(std::move(LMFramebuffer));
|
||||
deletelist->Add(std::move(LMView));
|
||||
deletelist->Add(std::move(ZMinMaxFramebuffer));
|
||||
deletelist->Add(std::move(DepthOnlyView));
|
||||
deletelist->Add(std::move(View));
|
||||
|
|
@ -41,8 +37,8 @@ public:
|
|||
std::unique_ptr<VulkanFramebuffer> PPFramebuffer;
|
||||
std::unique_ptr<VulkanFramebuffer> ZMinMaxFramebuffer;
|
||||
std::map<VkRenderPassKey, std::unique_ptr<VulkanFramebuffer>> RSFramebuffers;
|
||||
std::vector<std::unique_ptr<VulkanImageView>> LMViews;
|
||||
std::vector<std::unique_ptr<VulkanFramebuffer>> LMFramebuffers;
|
||||
std::unique_ptr<VulkanImageView> LMView;
|
||||
std::unique_ptr<VulkanFramebuffer> LMFramebuffer;
|
||||
};
|
||||
|
||||
class VkImageTransition
|
||||
|
|
|
|||
|
|
@ -57,13 +57,15 @@ void VkTextureManager::Deinit()
|
|||
RemovePPTexture(PPTextures.back());
|
||||
}
|
||||
|
||||
void VkTextureManager::BeginFrame()
|
||||
void VkTextureManager::BeginFrame(int lightmapTextureSize, int lightmapCount)
|
||||
{
|
||||
if (!Shadowmap.Image || Shadowmap.Image->width != gl_shadowmap_quality)
|
||||
{
|
||||
Shadowmap.Reset(fb);
|
||||
CreateShadowmap();
|
||||
}
|
||||
|
||||
SetLightmapCount(lightmapTextureSize, lightmapCount);
|
||||
}
|
||||
|
||||
void VkTextureManager::AddTexture(VkHardwareTexture* texture)
|
||||
|
|
@ -400,7 +402,7 @@ void VkTextureManager::CreateIrradiancemap()
|
|||
data.Push(0);
|
||||
data.Push(0);
|
||||
}
|
||||
CreateIrradiancemap(1, 6, std::move(data));
|
||||
CreateIrradiancemap(1, 1, std::move(data));
|
||||
}
|
||||
|
||||
void VkTextureManager::CreatePrefiltermap()
|
||||
|
|
@ -420,55 +422,55 @@ void VkTextureManager::CreatePrefiltermap()
|
|||
}
|
||||
}
|
||||
}
|
||||
CreatePrefiltermap(size, 6, std::move(data));
|
||||
CreatePrefiltermap(size, 1, std::move(data));
|
||||
}
|
||||
|
||||
void VkTextureManager::CreateIrradiancemap(int size, int count, const TArray<uint16_t>& newPixelData)
|
||||
void VkTextureManager::CreateIrradiancemap(int size, int cubeCount, const TArray<uint16_t>& srcPixels)
|
||||
{
|
||||
if (Irradiancemap.Size == size && Irradiancemap.Count == count && newPixelData.Size() == 0)
|
||||
return;
|
||||
|
||||
Irradiancemap.Size = size;
|
||||
Irradiancemap.Count = count;
|
||||
for (auto& tex : Irradiancemaps)
|
||||
tex.Reset(fb);
|
||||
Irradiancemaps.clear();
|
||||
Irradiancemaps.resize(cubeCount);
|
||||
|
||||
int w = size;
|
||||
int h = size;
|
||||
int pixelsize = 8;
|
||||
|
||||
Irradiancemap.Image.Reset(fb);
|
||||
for (int i = 0; i < cubeCount; i++)
|
||||
{
|
||||
Irradiancemaps[i].Image = ImageBuilder()
|
||||
.Size(w, h, 1, 6)
|
||||
.Format(VK_FORMAT_R16G16B16A16_SFLOAT)
|
||||
.Usage(VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT)
|
||||
.Flags(VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT)
|
||||
.DebugName("VkTextureManager.Irradiancemap")
|
||||
.Create(fb->GetDevice());
|
||||
|
||||
Irradiancemap.Image.Image = ImageBuilder()
|
||||
.Size(w, h, 1, count)
|
||||
.Format(VK_FORMAT_R16G16B16A16_SFLOAT)
|
||||
.Usage(VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT)
|
||||
.Flags(VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT)
|
||||
.DebugName("VkTextureManager.Irradiancemap")
|
||||
.Create(fb->GetDevice());
|
||||
|
||||
Irradiancemap.Image.View = ImageViewBuilder()
|
||||
.Type(VK_IMAGE_VIEW_TYPE_CUBE_ARRAY)
|
||||
.Image(Irradiancemap.Image.Image.get(), VK_FORMAT_R16G16B16A16_SFLOAT)
|
||||
.DebugName("VkTextureManager.IrradiancemapView")
|
||||
.Create(fb->GetDevice());
|
||||
Irradiancemaps[i].View = ImageViewBuilder()
|
||||
.Type(VK_IMAGE_VIEW_TYPE_CUBE)
|
||||
.Image(Irradiancemaps[i].Image.get(), VK_FORMAT_R16G16B16A16_SFLOAT)
|
||||
.DebugName("VkTextureManager.IrradiancemapView")
|
||||
.Create(fb->GetDevice());
|
||||
}
|
||||
|
||||
auto cmdbuffer = fb->GetCommands()->GetTransferCommands();
|
||||
|
||||
assert(newPixelData.Size() == (size_t)w * h * count * 3);
|
||||
|
||||
if (count > 0 && newPixelData.Size() == (size_t)w * h * count * 3)
|
||||
if (srcPixels.size() != 0)
|
||||
{
|
||||
int totalSize = w * h * count * pixelsize;
|
||||
if (srcPixels.size() != w * h * 3 * 6 * cubeCount)
|
||||
I_FatalError("Invalid pixels array passed to VkTextureManager.CreateIrradiancemap");
|
||||
|
||||
int totalSize = w * h * pixelsize * 6 * cubeCount;
|
||||
auto stagingBuffer = BufferBuilder()
|
||||
.Size(totalSize)
|
||||
.Usage(VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VMA_MEMORY_USAGE_CPU_ONLY)
|
||||
.DebugName("VkRenderBuffers.IrradiancemapStagingBuffer")
|
||||
.DebugName("VkTextureManager.CubeTextureListStagingBuffer")
|
||||
.Create(fb->GetDevice());
|
||||
|
||||
uint16_t one = 0x3c00; // half-float 1.0
|
||||
const uint16_t* src = newPixelData.Data();
|
||||
const uint16_t* src = srcPixels.data();
|
||||
uint16_t* data = (uint16_t*)stagingBuffer->Map(0, totalSize);
|
||||
for (int i = w * h * count; i > 0; i--)
|
||||
for (int i = w * h * 6 * cubeCount; i > 0; i--)
|
||||
{
|
||||
*(data++) = *(src++);
|
||||
*(data++) = *(src++);
|
||||
|
|
@ -477,77 +479,85 @@ void VkTextureManager::CreateIrradiancemap(int size, int count, const TArray<uin
|
|||
}
|
||||
stagingBuffer->Unmap();
|
||||
|
||||
VkImageTransition()
|
||||
.AddImage(&Irradiancemap.Image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, true, 0, 1, 0, count)
|
||||
.Execute(cmdbuffer);
|
||||
VkImageTransition barrier0;
|
||||
for (int i = 0; i < cubeCount; i++)
|
||||
barrier0.AddImage(&Irradiancemaps[i], VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, true, 0, 1, 0, 6);
|
||||
barrier0.Execute(cmdbuffer);
|
||||
|
||||
VkBufferImageCopy region = {};
|
||||
region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
region.imageSubresource.layerCount = count;
|
||||
region.imageExtent.depth = 1;
|
||||
region.imageExtent.width = w;
|
||||
region.imageExtent.height = h;
|
||||
cmdbuffer->copyBufferToImage(stagingBuffer->buffer, Irradiancemap.Image.Image->image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion);
|
||||
for (int i = 0; i < cubeCount; i++)
|
||||
{
|
||||
VkBufferImageCopy region = {};
|
||||
region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
region.imageSubresource.layerCount = 6;
|
||||
region.imageExtent.depth = 1;
|
||||
region.imageExtent.width = w;
|
||||
region.imageExtent.height = h;
|
||||
region.bufferOffset = w * h * pixelsize * 6 * i;
|
||||
cmdbuffer->copyBufferToImage(stagingBuffer->buffer, Irradiancemaps[i].Image->image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion);
|
||||
}
|
||||
|
||||
fb->GetCommands()->TransferDeleteList->Add(std::move(stagingBuffer));
|
||||
}
|
||||
|
||||
VkImageTransition()
|
||||
.AddImage(&Irradiancemap.Image, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, false, 0, 1, 0, count)
|
||||
.Execute(cmdbuffer);
|
||||
VkImageTransition barrier1;
|
||||
for (int i = 0; i < cubeCount; i++)
|
||||
barrier1.AddImage(&Irradiancemaps[i], VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, false, 0, 1, 0, 6);
|
||||
barrier1.Execute(cmdbuffer);
|
||||
}
|
||||
|
||||
void VkTextureManager::CreatePrefiltermap(int size, int count, const TArray<uint16_t>& newPixelData)
|
||||
void VkTextureManager::CreatePrefiltermap(int size, int cubeCount, const TArray<uint16_t>& srcPixels)
|
||||
{
|
||||
if (Prefiltermap.Size == size && Prefiltermap.Count == count && newPixelData.Size() == 0)
|
||||
return;
|
||||
|
||||
Prefiltermap.Size = size;
|
||||
Prefiltermap.Count = count;
|
||||
for (auto& tex : Prefiltermaps)
|
||||
tex.Reset(fb);
|
||||
Prefiltermaps.clear();
|
||||
Prefiltermaps.resize(cubeCount);
|
||||
|
||||
int w = size;
|
||||
int h = size;
|
||||
int pixelsize = 8;
|
||||
int miplevels = MAX_REFLECTION_LOD + 1;
|
||||
|
||||
Prefiltermap.Image.Reset(fb);
|
||||
for (int i = 0; i < cubeCount; i++)
|
||||
{
|
||||
Prefiltermaps[i].Image = ImageBuilder()
|
||||
.Size(w, h, miplevels, 6)
|
||||
.Format(VK_FORMAT_R16G16B16A16_SFLOAT)
|
||||
.Usage(VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT)
|
||||
.Flags(VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT)
|
||||
.DebugName("VkTextureManager.Prefiltermap")
|
||||
.Create(fb->GetDevice());
|
||||
|
||||
Prefiltermap.Image.Image = ImageBuilder()
|
||||
.Size(w, h, miplevels, count)
|
||||
.Format(VK_FORMAT_R16G16B16A16_SFLOAT)
|
||||
.Usage(VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT)
|
||||
.Flags(VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT)
|
||||
.DebugName("VkTextureManager.Prefiltermap")
|
||||
.Create(fb->GetDevice());
|
||||
|
||||
Prefiltermap.Image.View = ImageViewBuilder()
|
||||
.Type(VK_IMAGE_VIEW_TYPE_CUBE_ARRAY)
|
||||
.Image(Prefiltermap.Image.Image.get(), VK_FORMAT_R16G16B16A16_SFLOAT)
|
||||
.DebugName("VkTextureManager.PrefiltermapView")
|
||||
.Create(fb->GetDevice());
|
||||
Prefiltermaps[i].View = ImageViewBuilder()
|
||||
.Type(VK_IMAGE_VIEW_TYPE_CUBE)
|
||||
.Image(Prefiltermaps[i].Image.get(), VK_FORMAT_R16G16B16A16_SFLOAT)
|
||||
.DebugName("VkTextureManager.PrefiltermapView")
|
||||
.Create(fb->GetDevice());
|
||||
}
|
||||
|
||||
auto cmdbuffer = fb->GetCommands()->GetTransferCommands();
|
||||
|
||||
int totalSize = 0;
|
||||
for (int level = 0; level < miplevels; level++)
|
||||
if (srcPixels.size() != 0)
|
||||
{
|
||||
int mipwidth = std::max(w >> level, 1);
|
||||
int mipheight = std::max(h >> level, 1);
|
||||
totalSize += mipwidth * mipheight * count;
|
||||
}
|
||||
assert(newPixelData.Size() == (size_t)totalSize * 3);
|
||||
int totalSize = 0;
|
||||
for (int level = 0; level < miplevels; level++)
|
||||
{
|
||||
int mipwidth = std::max(w >> level, 1);
|
||||
int mipheight = std::max(h >> level, 1);
|
||||
totalSize += mipwidth * mipheight * 6 * cubeCount;
|
||||
}
|
||||
|
||||
if (srcPixels.size() != totalSize * 3)
|
||||
I_FatalError("Invalid pixels array passed to VkTextureManager.CreatePrefiltermap");
|
||||
|
||||
if (count > 0 && newPixelData.Size() == (size_t)totalSize * 3)
|
||||
{
|
||||
auto stagingBuffer = BufferBuilder()
|
||||
.Size(totalSize * pixelsize)
|
||||
.Usage(VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VMA_MEMORY_USAGE_CPU_ONLY)
|
||||
.DebugName("VkTextureManager.PrefiltermapStagingBuffer")
|
||||
.DebugName("VkTextureManager.CreatePrefiltermap")
|
||||
.Create(fb->GetDevice());
|
||||
|
||||
uint16_t one = 0x3c00; // half-float 1.0
|
||||
const uint16_t* src = newPixelData.Data();
|
||||
uint16_t* data = (uint16_t*)stagingBuffer->Map(0, totalSize * pixelsize);
|
||||
const uint16_t* src = srcPixels.data();
|
||||
uint16_t* data = (uint16_t*)stagingBuffer->Map(0, totalSize);
|
||||
for (int i = 0; i < totalSize; i++)
|
||||
{
|
||||
*(data++) = *(src++);
|
||||
|
|
@ -557,95 +567,121 @@ void VkTextureManager::CreatePrefiltermap(int size, int count, const TArray<uint
|
|||
}
|
||||
stagingBuffer->Unmap();
|
||||
|
||||
VkImageTransition()
|
||||
.AddImage(&Prefiltermap.Image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, true, 0, miplevels, 0, count)
|
||||
.Execute(cmdbuffer);
|
||||
VkImageTransition barrier0;
|
||||
for (int i = 0; i < cubeCount; i++)
|
||||
barrier0.AddImage(&Prefiltermaps[i], VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, true, 0, miplevels, 0, 6);
|
||||
barrier0.Execute(cmdbuffer);
|
||||
|
||||
int offset = 0;
|
||||
for (int i = 0; i < count; ++i)
|
||||
for (int i = 0; i < cubeCount; i++)
|
||||
{
|
||||
for (int level = 0; level < miplevels; level++)
|
||||
for (int side = 0; side < 6; side++)
|
||||
{
|
||||
int mipwidth = std::max(w >> level, 1);
|
||||
int mipheight = std::max(h >> level, 1);
|
||||
for (int level = 0; level < miplevels; level++)
|
||||
{
|
||||
int mipwidth = std::max(w >> level, 1);
|
||||
int mipheight = std::max(h >> level, 1);
|
||||
|
||||
VkBufferImageCopy region = {};
|
||||
region.bufferOffset = offset;
|
||||
region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
region.imageSubresource.layerCount = 1;
|
||||
region.imageSubresource.baseArrayLayer = i;
|
||||
region.imageSubresource.mipLevel = level;
|
||||
region.imageExtent.depth = 1;
|
||||
region.imageExtent.width = mipwidth;
|
||||
region.imageExtent.height = mipheight;
|
||||
cmdbuffer->copyBufferToImage(stagingBuffer->buffer, Prefiltermap.Image.Image->image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion);
|
||||
VkBufferImageCopy region = {};
|
||||
region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
region.imageSubresource.baseArrayLayer = side;
|
||||
region.imageSubresource.layerCount = 1;
|
||||
region.imageSubresource.mipLevel = level;
|
||||
region.imageExtent.depth = 1;
|
||||
region.imageExtent.width = mipwidth;
|
||||
region.imageExtent.height = mipheight;
|
||||
region.bufferOffset = offset;
|
||||
cmdbuffer->copyBufferToImage(stagingBuffer->buffer, Prefiltermaps[i].Image->image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion);
|
||||
|
||||
offset += mipwidth * mipheight * pixelsize;
|
||||
offset += mipwidth * mipheight * pixelsize;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fb->GetCommands()->TransferDeleteList->Add(std::move(stagingBuffer));
|
||||
}
|
||||
|
||||
VkImageTransition()
|
||||
.AddImage(&Prefiltermap.Image, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, false, 0, miplevels, 0, count)
|
||||
.Execute(cmdbuffer);
|
||||
VkImageTransition barrier1;
|
||||
for (int i = 0; i < cubeCount; i++)
|
||||
barrier1.AddImage(&Prefiltermaps[i], VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, false, 0, miplevels, 0, 6);
|
||||
barrier1.Execute(cmdbuffer);
|
||||
}
|
||||
|
||||
void VkTextureManager::CreateLightmap(int newLMTextureSize, int newLMTextureCount, TArray<uint16_t>&& newPixelData)
|
||||
void VkTextureManager::SetLightmapCount(int size, int count)
|
||||
{
|
||||
if (newLMTextureCount == 0) // If there is no lightmap we create a dummy texture to simplify code elsewhere
|
||||
{
|
||||
newLMTextureSize = 1;
|
||||
newLMTextureCount = 1;
|
||||
newPixelData = {};
|
||||
}
|
||||
|
||||
if (Lightmap.Size == newLMTextureSize && Lightmap.Count == newLMTextureCount + 1 && newPixelData.Size() == 0)
|
||||
int startIndex = Lightmaps.size();
|
||||
if (startIndex >= count)
|
||||
return;
|
||||
|
||||
Lightmap.Size = newLMTextureSize;
|
||||
Lightmaps.resize(count);
|
||||
|
||||
// Always create minimum 16 textures with 4 additional than the initial watermark
|
||||
// To do: add support for expanding the texture dynamically instead
|
||||
Lightmap.Count = std::max(newLMTextureCount, 12) + 4;
|
||||
|
||||
int w = newLMTextureSize;
|
||||
int h = newLMTextureSize;
|
||||
int count = newLMTextureCount;
|
||||
int pixelsize = 8;
|
||||
for (int i = startIndex; i < count; i++)
|
||||
{
|
||||
Lightmaps[i].Image = ImageBuilder()
|
||||
.Size(size, size)
|
||||
.Format(VK_FORMAT_R16G16B16A16_SFLOAT)
|
||||
.Usage(VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT)
|
||||
.DebugName("VkTextureManager.Lightmap")
|
||||
.Create(fb->GetDevice());
|
||||
|
||||
Lightmap.Image.Reset(fb);
|
||||
|
||||
Lightmap.Image.Image = ImageBuilder()
|
||||
.Size(w, h, 1, Lightmap.Count)
|
||||
.Format(VK_FORMAT_R16G16B16A16_SFLOAT)
|
||||
.Usage(VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT)
|
||||
.DebugName("VkTextureManager.Lightmap")
|
||||
.Create(fb->GetDevice());
|
||||
|
||||
Lightmap.Image.View = ImageViewBuilder()
|
||||
.Type(VK_IMAGE_VIEW_TYPE_2D_ARRAY)
|
||||
.Image(Lightmap.Image.Image.get(), VK_FORMAT_R16G16B16A16_SFLOAT)
|
||||
.DebugName("VkTextureManager.LightmapView")
|
||||
.Create(fb->GetDevice());
|
||||
Lightmaps[i].View = ImageViewBuilder()
|
||||
.Type(VK_IMAGE_VIEW_TYPE_2D)
|
||||
.Image(Lightmaps[i].Image.get(), VK_FORMAT_R16G16B16A16_SFLOAT)
|
||||
.DebugName("VkTextureManager.LightmapView")
|
||||
.Create(fb->GetDevice());
|
||||
}
|
||||
|
||||
auto cmdbuffer = fb->GetCommands()->GetTransferCommands();
|
||||
|
||||
if (count > 0 && newPixelData.Size() >= (size_t)w * h * count * 3)
|
||||
VkImageTransition barrier;
|
||||
for (int i = startIndex; i < count; i++)
|
||||
barrier.AddImage(&Lightmaps[i], VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, false);
|
||||
barrier.Execute(cmdbuffer);
|
||||
}
|
||||
|
||||
void VkTextureManager::CreateLightmap(int size, int count, const TArray<uint16_t>& srcPixels)
|
||||
{
|
||||
for (auto& tex : Lightmaps)
|
||||
tex.Reset(fb);
|
||||
Lightmaps.clear();
|
||||
Lightmaps.resize(count);
|
||||
|
||||
int w = size;
|
||||
int h = size;
|
||||
int pixelsize = 8;
|
||||
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
assert(newPixelData.Size() == (size_t)w * h * count * 3);
|
||||
Lightmaps[i].Image = ImageBuilder()
|
||||
.Size(w, h)
|
||||
.Format(VK_FORMAT_R16G16B16A16_SFLOAT)
|
||||
.Usage(VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT)
|
||||
.DebugName("VkTextureManager.Lightmap")
|
||||
.Create(fb->GetDevice());
|
||||
|
||||
int totalSize = w * h * count * pixelsize;
|
||||
Lightmaps[i].View = ImageViewBuilder()
|
||||
.Type(VK_IMAGE_VIEW_TYPE_2D)
|
||||
.Image(Lightmaps[i].Image.get(), VK_FORMAT_R16G16B16A16_SFLOAT)
|
||||
.DebugName("VkTextureManager.LightmapView")
|
||||
.Create(fb->GetDevice());
|
||||
}
|
||||
|
||||
auto cmdbuffer = fb->GetCommands()->GetTransferCommands();
|
||||
|
||||
if (srcPixels.size() != 0)
|
||||
{
|
||||
if (srcPixels.size() != w * h * 3 * count)
|
||||
I_FatalError("Invalid pixels array passed to VkTextureManager.CreateLightmap");
|
||||
|
||||
int totalSize = w * h * pixelsize * count;
|
||||
auto stagingBuffer = BufferBuilder()
|
||||
.Size(totalSize)
|
||||
.Usage(VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VMA_MEMORY_USAGE_CPU_ONLY)
|
||||
.DebugName("VkTextureManager.LightmapStagingBuffer")
|
||||
.DebugName("VkTextureManager.TextureListStagingBuffer")
|
||||
.Create(fb->GetDevice());
|
||||
|
||||
uint16_t one = 0x3c00; // half-float 1.0
|
||||
const uint16_t* src = newPixelData.Data();
|
||||
const uint16_t* src = srcPixels.data();
|
||||
uint16_t* data = (uint16_t*)stagingBuffer->Map(0, totalSize);
|
||||
for (int i = w * h * count; i > 0; i--)
|
||||
{
|
||||
|
|
@ -656,31 +692,42 @@ void VkTextureManager::CreateLightmap(int newLMTextureSize, int newLMTextureCoun
|
|||
}
|
||||
stagingBuffer->Unmap();
|
||||
|
||||
VkImageTransition()
|
||||
.AddImage(&Lightmap.Image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, true, 0, 1, 0, Lightmap.Count)
|
||||
.Execute(cmdbuffer);
|
||||
VkImageTransition barrier0;
|
||||
for (int i = 0; i < count; i++)
|
||||
barrier0.AddImage(&Lightmaps[i], VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, true);
|
||||
barrier0.Execute(cmdbuffer);
|
||||
|
||||
VkBufferImageCopy region = {};
|
||||
region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
region.imageSubresource.layerCount = count;
|
||||
region.imageExtent.depth = 1;
|
||||
region.imageExtent.width = w;
|
||||
region.imageExtent.height = h;
|
||||
cmdbuffer->copyBufferToImage(stagingBuffer->buffer, Lightmap.Image.Image->image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion);
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
VkBufferImageCopy region = {};
|
||||
region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
region.imageSubresource.layerCount = 1;
|
||||
region.imageExtent.depth = 1;
|
||||
region.imageExtent.width = w;
|
||||
region.imageExtent.height = h;
|
||||
region.bufferOffset = w * h * pixelsize * i;
|
||||
cmdbuffer->copyBufferToImage(stagingBuffer->buffer, Lightmaps[i].Image->image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion);
|
||||
}
|
||||
|
||||
fb->GetCommands()->TransferDeleteList->Add(std::move(stagingBuffer));
|
||||
|
||||
newPixelData.Clear();
|
||||
}
|
||||
|
||||
VkImageTransition()
|
||||
.AddImage(&Lightmap.Image, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, false, 0, 1, 0, Lightmap.Count)
|
||||
.Execute(cmdbuffer);
|
||||
VkImageTransition barrier1;
|
||||
for (int i = 0; i < count; i++)
|
||||
barrier1.AddImage(&Lightmaps[i], VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, false);
|
||||
barrier1.Execute(cmdbuffer);
|
||||
}
|
||||
|
||||
void VkTextureManager::DownloadLightmap(int arrayIndex, uint16_t* buffer)
|
||||
{
|
||||
unsigned int totalSize = Lightmap.Size * Lightmap.Size * 4;
|
||||
DownloadTexture(&Lightmaps[arrayIndex], buffer);
|
||||
}
|
||||
|
||||
void VkTextureManager::DownloadTexture(VkTextureImage* texture, uint16_t* buffer)
|
||||
{
|
||||
int width = texture->Image->width;
|
||||
int height = texture->Image->height;
|
||||
int totalSize = width * height * 4;
|
||||
|
||||
auto stagingBuffer = BufferBuilder()
|
||||
.Size(totalSize * sizeof(uint16_t))
|
||||
|
|
@ -690,23 +737,22 @@ void VkTextureManager::DownloadLightmap(int arrayIndex, uint16_t* buffer)
|
|||
|
||||
auto cmdbuffer = fb->GetCommands()->GetTransferCommands();
|
||||
|
||||
PipelineBarrier()
|
||||
.AddImage(Lightmap.Image.Image.get(), VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, VK_ACCESS_SHADER_READ_BIT, VK_ACCESS_TRANSFER_READ_BIT, VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, arrayIndex, 1)
|
||||
.Execute(cmdbuffer, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
|
||||
VkImageTransition()
|
||||
.AddImage(texture, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, false)
|
||||
.Execute(cmdbuffer);
|
||||
|
||||
VkBufferImageCopy region = {};
|
||||
region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
region.imageSubresource.baseArrayLayer = arrayIndex;
|
||||
region.imageSubresource.layerCount = 1;
|
||||
region.imageSubresource.mipLevel = 0;
|
||||
region.imageExtent.width = Lightmap.Size;
|
||||
region.imageExtent.height = Lightmap.Size;
|
||||
region.imageExtent.width = width;
|
||||
region.imageExtent.height = height;
|
||||
region.imageExtent.depth = 1;
|
||||
cmdbuffer->copyImageToBuffer(Lightmap.Image.Image->image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, stagingBuffer->buffer, 1, ®ion);
|
||||
cmdbuffer->copyImageToBuffer(texture->Image->image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, stagingBuffer->buffer, 1, ®ion);
|
||||
|
||||
PipelineBarrier()
|
||||
.AddImage(Lightmap.Image.Image.get(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_ACCESS_TRANSFER_READ_BIT, VK_ACCESS_SHADER_READ_BIT, VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, arrayIndex, 1)
|
||||
.Execute(cmdbuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
|
||||
VkImageTransition()
|
||||
.AddImage(texture, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, false)
|
||||
.Execute(cmdbuffer);
|
||||
|
||||
fb->GetCommands()->WaitForCommands(false);
|
||||
|
||||
|
|
|
|||
|
|
@ -26,11 +26,13 @@ public:
|
|||
|
||||
void Deinit();
|
||||
|
||||
void BeginFrame();
|
||||
void BeginFrame(int lightmapTextureSize, int lightmapCount);
|
||||
|
||||
void CreateLightmap(int size, int count, TArray<uint16_t>&& data);
|
||||
void CreateIrradiancemap(int size, int count, const TArray<uint16_t>& data);
|
||||
void CreatePrefiltermap(int size, int count, const TArray<uint16_t>& data);
|
||||
void SetLightmapCount(int size, int count);
|
||||
|
||||
void CreateLightmap(int size, int count, const TArray<uint16_t>& data);
|
||||
void CreateIrradiancemap(int size, int cubeCount, const TArray<uint16_t>& data);
|
||||
void CreatePrefiltermap(int size, int cubeCount, const TArray<uint16_t>& data);
|
||||
void DownloadLightmap(int arrayIndex, uint16_t* buffer);
|
||||
|
||||
void SetGamePalette();
|
||||
|
|
@ -58,13 +60,9 @@ public:
|
|||
int GetHWTextureCount() { return (int)Textures.size(); }
|
||||
|
||||
VkTextureImage Shadowmap;
|
||||
|
||||
struct
|
||||
{
|
||||
VkTextureImage Image;
|
||||
int Size = 0;
|
||||
int Count = 0;
|
||||
} Lightmap, Irradiancemap, Prefiltermap;
|
||||
std::vector<VkTextureImage> Lightmaps;
|
||||
std::vector<VkTextureImage> Irradiancemaps;
|
||||
std::vector<VkTextureImage> Prefiltermaps;
|
||||
|
||||
static const int MAX_REFLECTION_LOD = 4; // Note: must match what lightmodel_pbr.glsl expects
|
||||
|
||||
|
|
@ -83,6 +81,7 @@ private:
|
|||
void CreateLightmap();
|
||||
void CreateIrradiancemap();
|
||||
void CreatePrefiltermap();
|
||||
void DownloadTexture(VkTextureImage* texture, uint16_t* buffer);
|
||||
|
||||
void StartWorkerThread();
|
||||
void StopWorkerThread();
|
||||
|
|
|
|||
|
|
@ -402,8 +402,7 @@ void VkLightmapper::CopyResult()
|
|||
if (pixels == 0)
|
||||
return;
|
||||
|
||||
VkTextureImage* destTexture = &fb->GetTextureManager()->Lightmap.Image;
|
||||
int destSize = fb->GetTextureManager()->Lightmap.Size;
|
||||
std::vector<VkTextureImage>& destTexture = fb->GetTextureManager()->Lightmaps;
|
||||
|
||||
auto cmdbuffer = fb->GetCommands()->GetTransferCommands();
|
||||
|
||||
|
|
@ -415,7 +414,7 @@ void VkLightmapper::CopyResult()
|
|||
for (unsigned int i = 0, count = copylists.Size(); i < count; i++)
|
||||
{
|
||||
if (copylists[i].Size() > 0)
|
||||
barrier0.AddImage(destTexture->Image.get(), VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_ACCESS_SHADER_READ_BIT, VK_ACCESS_COLOR_ATTACHMENT_READ_BIT, VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, i, 1);
|
||||
barrier0.AddImage(destTexture[i].Image.get(), VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_ACCESS_SHADER_READ_BIT, VK_ACCESS_COLOR_ATTACHMENT_READ_BIT, VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1);
|
||||
}
|
||||
barrier0.Execute(cmdbuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
|
||||
|
||||
|
|
@ -428,22 +427,18 @@ void VkLightmapper::CopyResult()
|
|||
if (list.Size() == 0)
|
||||
continue;
|
||||
|
||||
// Create framebuffer object if it doesn't exist
|
||||
if (i >= destTexture->LMFramebuffers.size())
|
||||
{
|
||||
destTexture->LMViews.resize(i + 1);
|
||||
destTexture->LMFramebuffers.resize(i + 1);
|
||||
}
|
||||
int destSize = destTexture[i].Image->width;
|
||||
|
||||
auto& framebuffer = destTexture->LMFramebuffers[i];
|
||||
// Create framebuffer object if it doesn't exist
|
||||
auto& framebuffer = destTexture[i].LMFramebuffer;
|
||||
if (!framebuffer)
|
||||
{
|
||||
auto& view = destTexture->LMViews[i];
|
||||
auto& view = destTexture[i].LMView;
|
||||
if (!view)
|
||||
{
|
||||
view = ImageViewBuilder()
|
||||
.Type(VK_IMAGE_VIEW_TYPE_2D)
|
||||
.Image(destTexture->Image.get(), VK_FORMAT_R16G16B16A16_SFLOAT, VK_IMAGE_ASPECT_COLOR_BIT, 0, i, 1, 1)
|
||||
.Image(destTexture[i].Image.get(), VK_FORMAT_R16G16B16A16_SFLOAT, VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1, 1)
|
||||
.DebugName("LMView")
|
||||
.Create(fb->GetDevice());
|
||||
}
|
||||
|
|
@ -504,7 +499,7 @@ void VkLightmapper::CopyResult()
|
|||
for (unsigned int i = 0, count = copylists.Size(); i < count; i++)
|
||||
{
|
||||
if (copylists[i].Size() > 0)
|
||||
barrier1.AddImage(destTexture->Image.get(), VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT, VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, i, 1);
|
||||
barrier1.AddImage(destTexture[i].Image.get(), VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT, VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1);
|
||||
}
|
||||
barrier1.Execute(cmdbuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
|
||||
|
||||
|
|
|
|||
|
|
@ -415,8 +415,8 @@ void VulkanRenderDevice::RenderEnvironmentMap(std::function<void(IntRect& bounds
|
|||
|
||||
void VulkanRenderDevice::UploadEnvironmentMaps(int cubemapCount, const TArray<uint16_t>& irradianceMaps, const TArray<uint16_t>& prefilterMaps)
|
||||
{
|
||||
mTextureManager->CreateIrradiancemap(32, 6 * cubemapCount, irradianceMaps);
|
||||
mTextureManager->CreatePrefiltermap(128, 6 * cubemapCount, prefilterMaps);
|
||||
mTextureManager->CreateIrradiancemap(32, cubemapCount, irradianceMaps);
|
||||
mTextureManager->CreatePrefiltermap(128, cubemapCount, prefilterMaps);
|
||||
}
|
||||
|
||||
void VulkanRenderDevice::PostProcessScene(bool swscene, int fixedcm, float flash, bool palettePostprocess, const std::function<void()> &afterBloomDrawEndScene2D)
|
||||
|
|
@ -638,7 +638,7 @@ void VulkanRenderDevice::BeginFrame()
|
|||
SetViewportRects(nullptr);
|
||||
mCommands->BeginFrame();
|
||||
mLevelMesh->BeginFrame();
|
||||
mTextureManager->BeginFrame();
|
||||
mTextureManager->BeginFrame(levelMesh->Lightmap.TextureSize, levelMesh->Lightmap.TextureCount);
|
||||
mScreenBuffers->BeginFrame(screen->mScreenViewport.width, screen->mScreenViewport.height, screen->mSceneViewport.width, screen->mSceneViewport.height);
|
||||
mSaveBuffers->BeginFrame(SAVEPICWIDTH, SAVEPICHEIGHT, SAVEPICWIDTH, SAVEPICHEIGHT);
|
||||
mRenderState->BeginFrame();
|
||||
|
|
|
|||
|
|
@ -458,6 +458,8 @@ void VkRenderState::ApplySurfaceUniforms()
|
|||
mSurfaceUniforms.uColormapIndex = 0;
|
||||
}
|
||||
|
||||
mSurfaceUniforms.uLightProbeIndex = fb->GetDescriptorSetManager()->GetLightProbeTextureIndex(mLightProbeIndex);
|
||||
|
||||
if (mMaterial.mChanged)
|
||||
{
|
||||
if (mMaterial.mMaterial)
|
||||
|
|
|
|||
|
|
@ -205,18 +205,6 @@ static void SetFlatVertex(FFlatVertex& ffv, vertex_t* vt, const secplane_t& plan
|
|||
ffv.lindex = -1.0f;
|
||||
}
|
||||
|
||||
static void SetFlatVertex(FFlatVertex& ffv, vertex_t* vt, const secplane_t& plane, float llu, float llv, float llindex)
|
||||
{
|
||||
ffv.x = (float)vt->fX();
|
||||
ffv.y = (float)vt->fY();
|
||||
ffv.z = (float)plane.ZatPoint(vt);
|
||||
ffv.u = (float)vt->fX() / 64.f;
|
||||
ffv.v = -(float)vt->fY() / 64.f;
|
||||
ffv.lu = llu;
|
||||
ffv.lv = llv;
|
||||
ffv.lindex = llindex;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Creates the vertices for one plane in one subsector w/lightmap support.
|
||||
|
|
@ -470,6 +458,10 @@ static void UpdatePlaneLightmap(FRenderState& renderstate, sector_t* sec, int pl
|
|||
vt->lv = luv.Y;
|
||||
vt->lindex = lindex;
|
||||
}
|
||||
else
|
||||
{
|
||||
vt->lindex = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
renderstate.UpdateShadowData(startvt, §or_vertices[startvt], countvt);
|
||||
|
|
|
|||
|
|
@ -1,2 +1,3 @@
|
|||
|
||||
layout(set = 2, binding = 0) uniform sampler2D textures[];
|
||||
layout(set = 2, binding = 0) uniform samplerCube cubeTextures[];
|
||||
|
|
|
|||
|
|
@ -1,18 +1,15 @@
|
|||
#include <shaders/binding_struct_definitions.glsl>
|
||||
|
||||
layout(set = 0, binding = 0) uniform sampler2D ShadowMap;
|
||||
layout(set = 0, binding = 1) uniform sampler2DArray LightMap;
|
||||
layout(set = 0, binding = 2) uniform sampler2D LinearDepth;
|
||||
layout(set = 0, binding = 3) uniform samplerCubeArray IrradianceMap;
|
||||
layout(set = 0, binding = 4) uniform samplerCubeArray PrefilterMap;
|
||||
layout(set = 0, binding = 1) uniform sampler2D LinearDepth;
|
||||
|
||||
#if defined(SUPPORTS_RAYQUERY)
|
||||
|
||||
layout(set = 0, binding = 5) uniform accelerationStructureEXT acc;
|
||||
layout(set = 0, binding = 2) uniform accelerationStructureEXT acc;
|
||||
|
||||
#else
|
||||
|
||||
layout(set = 0, binding = 5, std430) buffer readonly NodeBuffer
|
||||
layout(set = 0, binding = 2, std430) buffer readonly NodeBuffer
|
||||
{
|
||||
int nodesRoot;
|
||||
int nodebufferPadding1;
|
||||
|
|
@ -23,9 +20,9 @@ layout(set = 0, binding = 5, std430) buffer readonly NodeBuffer
|
|||
|
||||
#endif
|
||||
|
||||
layout(set = 0, binding = 6, std430) buffer readonly VertexBuffer { SurfaceVertex vertices[]; };
|
||||
layout(set = 0, binding = 7, std430) buffer readonly ElementBuffer { int elements[]; };
|
||||
layout(set = 0, binding = 8, std430) buffer readonly SurfaceIndexBuffer { uint surfaceIndices[]; };
|
||||
layout(set = 0, binding = 9, std430) buffer readonly SurfaceBuffer { SurfaceInfo surfaces[]; };
|
||||
layout(set = 0, binding = 10, std430) buffer readonly PortalBuffer { PortalInfo portals[]; };
|
||||
layout(set = 0, binding = 3, std430) buffer readonly VertexBuffer { SurfaceVertex vertices[]; };
|
||||
layout(set = 0, binding = 4, std430) buffer readonly ElementBuffer { int elements[]; };
|
||||
layout(set = 0, binding = 5, std430) buffer readonly SurfaceIndexBuffer { uint surfaceIndices[]; };
|
||||
layout(set = 0, binding = 6, std430) buffer readonly SurfaceBuffer { SurfaceInfo surfaces[]; };
|
||||
layout(set = 0, binding = 7, std430) buffer readonly PortalBuffer { PortalInfo portals[]; };
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
|
||||
layout(set = 2, binding = 0) uniform sampler2D textures[];
|
||||
layout(set = 2, binding = 0) uniform samplerCube cubeTextures[];
|
||||
|
||||
const int tex = 0;
|
||||
const int texture2 = 1;
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@
|
|||
|
||||
#define BrdfLUT 1 // the BRDF convoluted texture is always in this texture slot
|
||||
#define PaletteLUT 2 // the RGB666 lookup table from a color to the game palette is always in this texture slot
|
||||
#define LightmapsStart 3 // the lightmaps start at this texture slot
|
||||
|
||||
#define uObjectColor data[uDataIndex].uObjectColor
|
||||
#define uObjectColor2 data[uDataIndex].uObjectColor2
|
||||
|
|
|
|||
|
|
@ -52,9 +52,9 @@ vec4 getLightColor(Material material)
|
|||
|
||||
vec4 dynlight = uDynLightColor;
|
||||
|
||||
if (vLightmap.z >= 0.0)
|
||||
if (vLightmapIndex != -1)
|
||||
{
|
||||
dynlight.rgb += texture(LightMap, vLightmap).rgb;
|
||||
dynlight.rgb += texture(textures[nonuniformEXT(vLightmapIndex)], vLightmap.xy).rgb;
|
||||
}
|
||||
|
||||
dynlight.rgb += ProcessSWLight(material);
|
||||
|
|
@ -103,9 +103,9 @@ vec4 getLightColor(Material material)
|
|||
//
|
||||
// apply lightmaps
|
||||
//
|
||||
if (vLightmap.z >= 0.0)
|
||||
if (vLightmapIndex != -1)
|
||||
{
|
||||
color.rgb += texture(LightMap, vLightmap).rgb;
|
||||
color.rgb += texture(textures[nonuniformEXT(vLightmapIndex)], vLightmap.xy).rgb;
|
||||
}
|
||||
|
||||
//
|
||||
|
|
|
|||
|
|
@ -151,13 +151,13 @@ vec3 ProcessMaterialLight(Material material, vec3 ambientLight)
|
|||
|
||||
const float environmentScaleFactor = 1.0;
|
||||
|
||||
vec3 irradiance = texture(IrradianceMap, vec4(N, uLightProbeIndex)).rgb * environmentScaleFactor;
|
||||
vec3 irradiance = texture(cubeTextures[uLightProbeIndex], N).rgb * environmentScaleFactor;
|
||||
vec3 diffuse = irradiance * albedo;
|
||||
|
||||
kD *= 1.0 - metallic;
|
||||
const float MAX_REFLECTION_LOD = 4.0;
|
||||
vec3 R = reflect(-V, N);
|
||||
vec3 prefilteredColor = textureLod(PrefilterMap, vec4(R, uLightProbeIndex), roughness * MAX_REFLECTION_LOD).rgb * environmentScaleFactor;
|
||||
vec3 prefilteredColor = textureLod(cubeTextures[uLightProbeIndex + 1], R, roughness * MAX_REFLECTION_LOD).rgb * environmentScaleFactor;
|
||||
vec2 envBRDF = texture(textures[BrdfLUT], vec2(clamp(dot(N, V), 0.0, 1.0), roughness)).rg;
|
||||
vec3 specular = prefilteredColor * (F * envBRDF.x + envBRDF.y);
|
||||
|
||||
|
|
|
|||
|
|
@ -135,7 +135,11 @@ void main()
|
|||
#endif
|
||||
|
||||
#if !defined(SIMPLE) || defined(SIMPLE3D)
|
||||
vLightmap = vec3(aLightmap, aPosition.w);
|
||||
vLightmap = aLightmap;
|
||||
if (aPosition.w >= 0.0)
|
||||
vLightmapIndex = LightmapsStart + int(aPosition.w);
|
||||
else
|
||||
vLightmapIndex = -1;
|
||||
|
||||
pixelpos.xyz = worldcoord.xyz;
|
||||
pixelpos.w = -eyeCoordPos.z/eyeCoordPos.w;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue