Improve the builder syntax so that fewer temp variables are required to build vulkan objects

This commit is contained in:
Magnus Norddahl 2022-06-15 07:04:42 +02:00 committed by Christoph Oelckers
parent 386cb5bfb2
commit ed134c9b19
19 changed files with 975 additions and 827 deletions

View file

@ -80,12 +80,12 @@ void VkDescriptorSetManager::UpdateHWBufferSet()
HWBufferSet = HWBufferDescriptorPool->allocate(HWBufferSetLayout.get());
}
WriteDescriptors update;
update.addBuffer(HWBufferSet.get(), 0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, fb->GetBufferManager()->ViewpointUBO->mBuffer.get(), 0, sizeof(HWViewpointUniforms));
update.addBuffer(HWBufferSet.get(), 1, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, fb->GetBufferManager()->MatrixBuffer->UniformBuffer->mBuffer.get(), 0, sizeof(MatricesUBO));
update.addBuffer(HWBufferSet.get(), 2, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, fb->GetBufferManager()->StreamBuffer->UniformBuffer->mBuffer.get(), 0, sizeof(StreamUBO));
update.addBuffer(HWBufferSet.get(), 3, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, fb->GetBufferManager()->LightBufferSSO->mBuffer.get());
update.updateSets(fb->device);
WriteDescriptors()
.AddBuffer(HWBufferSet.get(), 0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, fb->GetBufferManager()->ViewpointUBO->mBuffer.get(), 0, sizeof(HWViewpointUniforms))
.AddBuffer(HWBufferSet.get(), 1, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, fb->GetBufferManager()->MatrixBuffer->UniformBuffer->mBuffer.get(), 0, sizeof(MatricesUBO))
.AddBuffer(HWBufferSet.get(), 2, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, fb->GetBufferManager()->StreamBuffer->UniformBuffer->mBuffer.get(), 0, sizeof(StreamUBO))
.AddBuffer(HWBufferSet.get(), 3, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, fb->GetBufferManager()->LightBufferSSO->mBuffer.get())
.Execute(fb->device);
}
void VkDescriptorSetManager::UpdateFixedSet()
@ -100,11 +100,11 @@ void VkDescriptorSetManager::UpdateFixedSet()
}
WriteDescriptors update;
update.addCombinedImageSampler(FixedSet.get(), 0, fb->GetTextureManager()->Shadowmap.View.get(), fb->GetSamplerManager()->ShadowmapSampler.get(), VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
update.addCombinedImageSampler(FixedSet.get(), 1, fb->GetTextureManager()->Lightmap.View.get(), fb->GetSamplerManager()->LightmapSampler.get(), VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
update.AddCombinedImageSampler(FixedSet.get(), 0, fb->GetTextureManager()->Shadowmap.View.get(), fb->GetSamplerManager()->ShadowmapSampler.get(), VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
update.AddCombinedImageSampler(FixedSet.get(), 1, fb->GetTextureManager()->Lightmap.View.get(), fb->GetSamplerManager()->LightmapSampler.get(), VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
if (fb->device->SupportsDeviceExtension(VK_KHR_RAY_QUERY_EXTENSION_NAME))
update.addAccelerationStructure(FixedSet.get(), 2, fb->GetRaytrace()->GetAccelStruct());
update.updateSets(fb->device);
update.AddAccelerationStructure(FixedSet.get(), 2, fb->GetRaytrace()->GetAccelStruct());
update.Execute(fb->device);
}
void VkDescriptorSetManager::ResetHWTextureSets()
@ -133,9 +133,9 @@ VulkanDescriptorSet* VkDescriptorSetManager::GetNullTextureDescriptorSet()
WriteDescriptors update;
for (int i = 0; i < SHADER_MIN_REQUIRED_TEXTURE_LAYERS; i++)
{
update.addCombinedImageSampler(NullTextureDescriptorSet.get(), i, fb->GetTextureManager()->GetNullTextureView(), fb->GetSamplerManager()->Get(CLAMP_XY_NOMIP), VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
update.AddCombinedImageSampler(NullTextureDescriptorSet.get(), i, fb->GetTextureManager()->GetNullTextureView(), fb->GetSamplerManager()->Get(CLAMP_XY_NOMIP), VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
}
update.updateSets(fb->device);
update.Execute(fb->device);
}
return NullTextureDescriptorSet.get();
@ -148,11 +148,11 @@ std::unique_ptr<VulkanDescriptorSet> VkDescriptorSetManager::AllocateTextureDesc
TextureDescriptorSetsLeft = 1000;
TextureDescriptorsLeft = 2000;
DescriptorPoolBuilder builder;
builder.addPoolSize(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, TextureDescriptorsLeft);
builder.setMaxSets(TextureDescriptorSetsLeft);
TextureDescriptorPools.push_back(builder.create(fb->device));
TextureDescriptorPools.back()->SetDebugName("VkDescriptorSetManager.TextureDescriptorPool");
TextureDescriptorPools.push_back(DescriptorPoolBuilder()
.AddPoolSize(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, TextureDescriptorsLeft)
.MaxSets(TextureDescriptorSetsLeft)
.DebugName("VkDescriptorSetManager.TextureDescriptorPool")
.Create(fb->device));
}
TextureDescriptorSetsLeft--;
@ -172,10 +172,10 @@ VulkanDescriptorSetLayout* VkDescriptorSetManager::GetTextureSetLayout(int numLa
DescriptorSetLayoutBuilder builder;
for (int i = 0; i < numLayers; i++)
{
builder.addBinding(i, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT);
builder.AddBinding(i, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT);
}
layout = builder.create(fb->device);
layout->SetDebugName("VkDescriptorSetManager.TextureSetLayout");
builder.DebugName("VkDescriptorSetManager.TextureSetLayout");
layout = builder.Create(fb->device);
return layout.get();
}
@ -205,19 +205,19 @@ VulkanDescriptorSet* VkDescriptorSetManager::GetInput(VkPPRenderPassSetup* passS
VulkanSampler* sampler = fb->GetSamplerManager()->Get(input.Filter, input.Wrap);
VkTextureImage* tex = fb->GetTextureManager()->GetTexture(input.Type, input.Texture);
write.addCombinedImageSampler(descriptors.get(), index, tex->DepthOnlyView ? tex->DepthOnlyView.get() : tex->View.get(), sampler, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
imageTransition.addImage(tex, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, false);
write.AddCombinedImageSampler(descriptors.get(), index, tex->DepthOnlyView ? tex->DepthOnlyView.get() : tex->View.get(), sampler, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
imageTransition.AddImage(tex, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, false);
}
if (bindShadowMapBuffers)
{
write.addBuffer(descriptors.get(), LIGHTNODES_BINDINGPOINT, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, fb->GetBufferManager()->LightNodes->mBuffer.get());
write.addBuffer(descriptors.get(), LIGHTLINES_BINDINGPOINT, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, fb->GetBufferManager()->LightLines->mBuffer.get());
write.addBuffer(descriptors.get(), LIGHTLIST_BINDINGPOINT, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, fb->GetBufferManager()->LightList->mBuffer.get());
write.AddBuffer(descriptors.get(), LIGHTNODES_BINDINGPOINT, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, fb->GetBufferManager()->LightNodes->mBuffer.get());
write.AddBuffer(descriptors.get(), LIGHTLINES_BINDINGPOINT, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, fb->GetBufferManager()->LightLines->mBuffer.get());
write.AddBuffer(descriptors.get(), LIGHTLIST_BINDINGPOINT, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, fb->GetBufferManager()->LightList->mBuffer.get());
}
write.updateSets(fb->device);
imageTransition.execute(fb->GetCommands()->GetDrawCommands());
write.Execute(fb->device);
imageTransition.Execute(fb->GetCommands()->GetDrawCommands());
VulkanDescriptorSet* set = descriptors.get();
fb->GetCommands()->DrawDeleteList->Add(std::move(descriptors));
@ -235,55 +235,55 @@ std::unique_ptr<VulkanDescriptorSet> VkDescriptorSetManager::AllocatePPDescripto
fb->GetCommands()->DrawDeleteList->Add(std::move(PPDescriptorPool));
}
DescriptorPoolBuilder builder;
builder.addPoolSize(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 200);
builder.addPoolSize(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 4);
builder.setMaxSets(100);
PPDescriptorPool = builder.create(fb->device);
PPDescriptorPool->SetDebugName("PPDescriptorPool");
PPDescriptorPool = DescriptorPoolBuilder()
.AddPoolSize(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 200)
.AddPoolSize(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 4)
.MaxSets(100)
.DebugName("PPDescriptorPool")
.Create(fb->device);
return PPDescriptorPool->allocate(layout);
}
void VkDescriptorSetManager::CreateHWBufferSetLayout()
{
DescriptorSetLayoutBuilder builder;
builder.addBinding(0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 1, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT);
builder.addBinding(1, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 1, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT);
builder.addBinding(2, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 1, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT);
builder.addBinding(3, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT);
HWBufferSetLayout = builder.create(fb->device);
HWBufferSetLayout->SetDebugName("VkDescriptorSetManager.HWBufferSetLayout");
HWBufferSetLayout = DescriptorSetLayoutBuilder()
.AddBinding(0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 1, VK_SHADER_STAGE_VERTEX_BIT | 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(2, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 1, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT)
.AddBinding(3, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT)
.DebugName("VkDescriptorSetManager.HWBufferSetLayout")
.Create(fb->device);
}
void VkDescriptorSetManager::CreateFixedSetLayout()
{
DescriptorSetLayoutBuilder builder;
builder.addBinding(0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT);
builder.addBinding(1, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT);
builder.AddBinding(0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT);
builder.AddBinding(1, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT);
if (fb->device->SupportsDeviceExtension(VK_KHR_RAY_QUERY_EXTENSION_NAME))
builder.addBinding(2, VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, 1, VK_SHADER_STAGE_FRAGMENT_BIT);
FixedSetLayout = builder.create(fb->device);
FixedSetLayout->SetDebugName("VkDescriptorSetManager.FixedSetLayout");
builder.AddBinding(2, VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, 1, VK_SHADER_STAGE_FRAGMENT_BIT);
builder.DebugName("VkDescriptorSetManager.FixedSetLayout");
FixedSetLayout = builder.Create(fb->device);
}
void VkDescriptorSetManager::CreateHWBufferPool()
{
DescriptorPoolBuilder poolbuilder;
poolbuilder.addPoolSize(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 3 * maxSets);
poolbuilder.addPoolSize(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1 * maxSets);
poolbuilder.setMaxSets(maxSets);
HWBufferDescriptorPool = poolbuilder.create(fb->device);
HWBufferDescriptorPool->SetDebugName("VkDescriptorSetManager.HWBufferDescriptorPool");
HWBufferDescriptorPool = DescriptorPoolBuilder()
.AddPoolSize(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 3 * maxSets)
.AddPoolSize(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1 * maxSets)
.MaxSets(maxSets)
.DebugName("VkDescriptorSetManager.HWBufferDescriptorPool")
.Create(fb->device);
}
void VkDescriptorSetManager::CreateFixedSetPool()
{
DescriptorPoolBuilder poolbuilder;
poolbuilder.addPoolSize(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 2 * maxSets);
poolbuilder.AddPoolSize(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 2 * maxSets);
if (fb->device->SupportsDeviceExtension(VK_KHR_RAY_QUERY_EXTENSION_NAME))
poolbuilder.addPoolSize(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, 1 * maxSets);
poolbuilder.setMaxSets(maxSets);
FixedDescriptorPool = poolbuilder.create(fb->device);
FixedDescriptorPool->SetDebugName("VkDescriptorSetManager.FixedDescriptorPool");
poolbuilder.AddPoolSize(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, 1 * maxSets);
poolbuilder.MaxSets(maxSets);
poolbuilder.DebugName("VkDescriptorSetManager.FixedDescriptorPool");
FixedDescriptorPool = poolbuilder.Create(fb->device);
}

View file

@ -55,9 +55,9 @@ void VkPostprocess::SetActiveRenderTarget()
{
auto buffers = fb->GetBuffers();
VkImageTransition imageTransition;
imageTransition.addImage(&buffers->PipelineImage[mCurrentPipelineImage], VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, false);
imageTransition.execute(fb->GetCommands()->GetDrawCommands());
VkImageTransition()
.AddImage(&buffers->PipelineImage[mCurrentPipelineImage], VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, false)
.Execute(fb->GetCommands()->GetDrawCommands());
fb->GetRenderState()->SetRenderTarget(&buffers->PipelineImage[mCurrentPipelineImage], nullptr, buffers->GetWidth(), buffers->GetHeight(), VK_FORMAT_R16G16B16A16_SFLOAT, VK_SAMPLE_COUNT_1_BIT);
}
@ -84,10 +84,10 @@ void VkPostprocess::BlitSceneToPostprocess()
mCurrentPipelineImage = 0;
VkImageTransition imageTransition;
imageTransition.addImage(&buffers->SceneColor, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, false);
imageTransition.addImage(&buffers->PipelineImage[mCurrentPipelineImage], VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, true);
imageTransition.execute(fb->GetCommands()->GetDrawCommands());
VkImageTransition()
.AddImage(&buffers->SceneColor, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, false)
.AddImage(&buffers->PipelineImage[mCurrentPipelineImage], VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, true)
.Execute(fb->GetCommands()->GetDrawCommands());
if (buffers->GetSceneSamples() != VK_SAMPLE_COUNT_1_BIT)
{
@ -136,12 +136,12 @@ void VkPostprocess::ImageTransitionScene(bool undefinedSrcLayout)
{
auto buffers = fb->GetBuffers();
VkImageTransition imageTransition;
imageTransition.addImage(&buffers->SceneColor, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, undefinedSrcLayout);
imageTransition.addImage(&buffers->SceneFog, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, undefinedSrcLayout);
imageTransition.addImage(&buffers->SceneNormal, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, undefinedSrcLayout);
imageTransition.addImage(&buffers->SceneDepthStencil, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, undefinedSrcLayout);
imageTransition.execute(fb->GetCommands()->GetDrawCommands());
VkImageTransition()
.AddImage(&buffers->SceneColor, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, undefinedSrcLayout)
.AddImage(&buffers->SceneFog, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, undefinedSrcLayout)
.AddImage(&buffers->SceneNormal, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, undefinedSrcLayout)
.AddImage(&buffers->SceneDepthStencil, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, undefinedSrcLayout)
.Execute(fb->GetCommands()->GetDrawCommands());
}
void VkPostprocess::BlitCurrentToImage(VkTextureImage *dstimage, VkImageLayout finallayout)
@ -151,10 +151,10 @@ void VkPostprocess::BlitCurrentToImage(VkTextureImage *dstimage, VkImageLayout f
auto srcimage = &fb->GetBuffers()->PipelineImage[mCurrentPipelineImage];
auto cmdbuffer = fb->GetCommands()->GetDrawCommands();
VkImageTransition imageTransition0;
imageTransition0.addImage(srcimage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, false);
imageTransition0.addImage(dstimage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, true);
imageTransition0.execute(cmdbuffer);
VkImageTransition()
.AddImage(srcimage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, false)
.AddImage(dstimage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, true)
.Execute(cmdbuffer);
VkImageBlit blit = {};
blit.srcOffsets[0] = { 0, 0, 0 };
@ -169,14 +169,15 @@ void VkPostprocess::BlitCurrentToImage(VkTextureImage *dstimage, VkImageLayout f
blit.dstSubresource.mipLevel = 0;
blit.dstSubresource.baseArrayLayer = 0;
blit.dstSubresource.layerCount = 1;
cmdbuffer->blitImage(
srcimage->Image->image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
dstimage->Image->image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
1, &blit, VK_FILTER_NEAREST);
VkImageTransition imageTransition1;
imageTransition1.addImage(dstimage, finallayout, false);
imageTransition1.execute(cmdbuffer);
VkImageTransition()
.AddImage(dstimage, finallayout, false)
.Execute(cmdbuffer);
}
void VkPostprocess::DrawPresentTexture(const IntRect &box, bool applyGamma, bool screenshot)
@ -277,9 +278,9 @@ void VkPostprocess::UpdateShadowMap()
VkPPRenderState renderstate(fb);
hw_postprocess.shadowmap.Update(&renderstate);
VkImageTransition imageTransition;
imageTransition.addImage(&fb->GetTextureManager()->Shadowmap, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, false);
imageTransition.execute(fb->GetCommands()->GetDrawCommands());
VkImageTransition()
.AddImage(&fb->GetTextureManager()->Shadowmap, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, false)
.Execute(fb->GetCommands()->GetDrawCommands());
screen->mShadowMap.FinishUpdate();
}

View file

@ -95,36 +95,36 @@ void VkRaytrace::CreateVertexAndIndexBuffers()
size_t vertexoffset = 0;
size_t indexoffset = vertexoffset + vertexbuffersize;
BufferBuilder tbuilder;
tbuilder.setUsage(VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VMA_MEMORY_USAGE_CPU_ONLY);
tbuilder.setSize(transferbuffersize);
transferBuffer = tbuilder.create(fb->device);
transferBuffer->SetDebugName("transferBuffer");
transferBuffer = BufferBuilder()
.Usage(VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VMA_MEMORY_USAGE_CPU_ONLY)
.Size(transferbuffersize)
.DebugName("transferBuffer")
.Create(fb->device);
uint8_t* data = (uint8_t*)transferBuffer->Map(0, transferbuffersize);
memcpy(data + vertexoffset, Mesh->MeshVertices.Data(), vertexbuffersize);
memcpy(data + indexoffset, Mesh->MeshElements.Data(), indexbuffersize);
transferBuffer->Unmap();
BufferBuilder vbuilder;
vbuilder.setUsage(VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT | VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT);
vbuilder.setSize(vertexbuffersize);
vertexBuffer = vbuilder.create(fb->device);
vertexBuffer->SetDebugName("vertexBuffer");
vertexBuffer = BufferBuilder()
.Usage(VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT | VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT)
.Size(vertexbuffersize)
.DebugName("vertexBuffer")
.Create(fb->device);
BufferBuilder ibuilder;
ibuilder.setUsage(VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT | VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT);
ibuilder.setSize(indexbuffersize);
indexBuffer = ibuilder.create(fb->device);
indexBuffer->SetDebugName("indexBuffer");
indexBuffer = BufferBuilder()
.Usage(VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT | VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT)
.Size(indexbuffersize)
.DebugName("indexBuffer")
.Create(fb->device);
fb->GetCommands()->GetTransferCommands()->copyBuffer(transferBuffer.get(), vertexBuffer.get(), vertexoffset);
fb->GetCommands()->GetTransferCommands()->copyBuffer(transferBuffer.get(), indexBuffer.get(), indexoffset);
// Finish transfer before using it for building
VkMemoryBarrier barrier = { VK_STRUCTURE_TYPE_MEMORY_BARRIER };
barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
fb->GetCommands()->GetTransferCommands()->pipelineBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR, 0, 1, &barrier, 0, nullptr, 0, nullptr);
PipelineBarrier()
.AddMemory(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT)
.Execute(fb->GetCommands()->GetTransferCommands(), VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR);
}
void VkRaytrace::CreateBottomLevelAccelerationStructure()
@ -158,11 +158,11 @@ void VkRaytrace::CreateBottomLevelAccelerationStructure()
VkAccelerationStructureBuildSizesInfoKHR sizeInfo = { VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_SIZES_INFO_KHR };
vkGetAccelerationStructureBuildSizesKHR(fb->device->device, VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR, &buildInfo, &maxPrimitiveCount, &sizeInfo);
BufferBuilder blbufbuilder;
blbufbuilder.setUsage(VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_STORAGE_BIT_KHR | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT);
blbufbuilder.setSize(sizeInfo.accelerationStructureSize);
blAccelStructBuffer = blbufbuilder.create(fb->device);
blAccelStructBuffer->SetDebugName("blAccelStructBuffer");
blAccelStructBuffer = BufferBuilder()
.Usage(VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_STORAGE_BIT_KHR | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT)
.Size(sizeInfo.accelerationStructureSize)
.DebugName("blAccelStructBuffer")
.Create(fb->device);
VkAccelerationStructureKHR blAccelStructHandle = {};
VkAccelerationStructureCreateInfoKHR createInfo = { VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_INFO_KHR };
@ -175,11 +175,11 @@ void VkRaytrace::CreateBottomLevelAccelerationStructure()
blAccelStruct = std::make_unique<VulkanAccelerationStructure>(fb->device, blAccelStructHandle);
blAccelStruct->SetDebugName("blAccelStruct");
BufferBuilder sbuilder;
sbuilder.setUsage(VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT);
sbuilder.setSize(sizeInfo.buildScratchSize);
blScratchBuffer = sbuilder.create(fb->device);
blScratchBuffer->SetDebugName("blScratchBuffer");
blScratchBuffer = BufferBuilder()
.Usage(VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT)
.Size(sizeInfo.buildScratchSize)
.DebugName("blScratchBuffer")
.Create(fb->device);
buildInfo.dstAccelerationStructure = blAccelStruct->accelstruct;
buildInfo.scratchData.deviceAddress = blScratchBuffer->GetDeviceAddress();
@ -187,10 +187,9 @@ void VkRaytrace::CreateBottomLevelAccelerationStructure()
fb->GetCommands()->GetTransferCommands()->buildAccelerationStructures(1, &buildInfo, rangeInfos);
// Finish building before using it as input to a toplevel accel structure
VkMemoryBarrier barrier = { VK_STRUCTURE_TYPE_MEMORY_BARRIER };
barrier.srcAccessMask = VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR;
barrier.dstAccessMask = VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR;
fb->GetCommands()->GetTransferCommands()->pipelineBarrier(VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR, VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR, 0, 1, &barrier, 0, nullptr, 0, nullptr);
PipelineBarrier()
.AddMemory(VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR, VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR)
.Execute(fb->GetCommands()->GetTransferCommands(), VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR, VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR);
}
void VkRaytrace::CreateTopLevelAccelerationStructure()
@ -203,20 +202,21 @@ void VkRaytrace::CreateTopLevelAccelerationStructure()
instance.flags = VK_GEOMETRY_INSTANCE_TRIANGLE_FACING_CULL_DISABLE_BIT_KHR;
instance.accelerationStructureReference = blAccelStruct->GetDeviceAddress();
BufferBuilder tbuilder;
tbuilder.setUsage(VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VMA_MEMORY_USAGE_CPU_ONLY);
tbuilder.setSize(sizeof(VkAccelerationStructureInstanceKHR));
tlTransferBuffer = tbuilder.create(fb->device);
tlTransferBuffer->SetDebugName("tlTransferBuffer");
tlTransferBuffer = BufferBuilder()
.Usage(VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VMA_MEMORY_USAGE_CPU_ONLY)
.Size(sizeof(VkAccelerationStructureInstanceKHR))
.DebugName("tlTransferBuffer")
.Create(fb->device);
auto data = (uint8_t*)tlTransferBuffer->Map(0, sizeof(VkAccelerationStructureInstanceKHR));
memcpy(data, &instance, sizeof(VkAccelerationStructureInstanceKHR));
tlTransferBuffer->Unmap();
BufferBuilder instbufbuilder;
instbufbuilder.setUsage(VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT | VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR | VK_BUFFER_USAGE_TRANSFER_DST_BIT);
instbufbuilder.setSize(sizeof(VkAccelerationStructureInstanceKHR));
tlInstanceBuffer = instbufbuilder.create(fb->device);
tlInstanceBuffer->SetDebugName("tlInstanceBuffer");
tlInstanceBuffer = BufferBuilder()
.Usage(VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT | VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR | VK_BUFFER_USAGE_TRANSFER_DST_BIT)
.Size(sizeof(VkAccelerationStructureInstanceKHR))
.DebugName("tlInstanceBuffer")
.Create(fb->device);
fb->GetCommands()->GetTransferCommands()->copyBuffer(tlTransferBuffer.get(), tlInstanceBuffer.get());
@ -249,11 +249,11 @@ void VkRaytrace::CreateTopLevelAccelerationStructure()
VkAccelerationStructureBuildSizesInfoKHR sizeInfo = { VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_SIZES_INFO_KHR };
vkGetAccelerationStructureBuildSizesKHR(fb->device->device, VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR, &buildInfo, &maxInstanceCount, &sizeInfo);
BufferBuilder tlbufbuilder;
tlbufbuilder.setUsage(VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_STORAGE_BIT_KHR | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT);
tlbufbuilder.setSize(sizeInfo.accelerationStructureSize);
tlAccelStructBuffer = tlbufbuilder.create(fb->device);
tlAccelStructBuffer->SetDebugName("tlAccelStructBuffer");
tlAccelStructBuffer = BufferBuilder()
.Usage(VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_STORAGE_BIT_KHR | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT)
.Size(sizeInfo.accelerationStructureSize)
.DebugName("tlAccelStructBuffer")
.Create(fb->device);
VkAccelerationStructureKHR tlAccelStructHandle = {};
VkAccelerationStructureCreateInfoKHR createInfo = { VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_INFO_KHR };
@ -265,11 +265,11 @@ void VkRaytrace::CreateTopLevelAccelerationStructure()
throw std::runtime_error("vkCreateAccelerationStructureKHR failed");
tlAccelStruct = std::make_unique<VulkanAccelerationStructure>(fb->device, tlAccelStructHandle);
BufferBuilder sbuilder;
sbuilder.setUsage(VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT);
sbuilder.setSize(sizeInfo.buildScratchSize);
tlScratchBuffer = sbuilder.create(fb->device);
tlScratchBuffer->SetDebugName("tlScratchBuffer");
tlScratchBuffer = BufferBuilder()
.Usage(VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT)
.Size(sizeInfo.buildScratchSize)
.DebugName("tlScratchBuffer")
.Create(fb->device);
buildInfo.dstAccelerationStructure = tlAccelStruct->accelstruct;
buildInfo.scratchData.deviceAddress = tlScratchBuffer->GetDeviceAddress();
@ -277,7 +277,7 @@ void VkRaytrace::CreateTopLevelAccelerationStructure()
fb->GetCommands()->GetTransferCommands()->buildAccelerationStructures(1, &buildInfo, rangeInfos);
// Finish building the accel struct before using as input in a fragment shader
PipelineBarrier finishbuildbarrier;
finishbuildbarrier.addMemory(VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR, VK_ACCESS_SHADER_READ_BIT);
finishbuildbarrier.execute(fb->GetCommands()->GetTransferCommands(), VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
PipelineBarrier()
.AddMemory(VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR, VK_ACCESS_SHADER_READ_BIT)
.Execute(fb->GetCommands()->GetTransferCommands(), VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
}

View file

@ -112,13 +112,13 @@ VulkanPipelineLayout* VkRenderPassManager::GetPipelineLayout(int numLayers)
auto descriptors = fb->GetDescriptorSetManager();
PipelineLayoutBuilder builder;
builder.addSetLayout(descriptors->GetFixedSetLayout());
builder.addSetLayout(descriptors->GetHWBufferSetLayout());
builder.AddSetLayout(descriptors->GetFixedSetLayout());
builder.AddSetLayout(descriptors->GetHWBufferSetLayout());
if (numLayers != 0)
builder.addSetLayout(descriptors->GetTextureSetLayout(numLayers));
builder.addPushConstantRange(VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(PushConstants));
layout = builder.create(fb->device);
layout->SetDebugName("VkRenderPassManager.PipelineLayout");
builder.AddSetLayout(descriptors->GetTextureSetLayout(numLayers));
builder.AddPushConstantRange(VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(PushConstants));
builder.DebugName("VkRenderPassManager.PipelineLayout");
layout = builder.Create(fb->device);
return layout.get();
}
@ -144,33 +144,33 @@ std::unique_ptr<VulkanRenderPass> VkRenderPassSetup::CreateRenderPass(int clearT
RenderPassBuilder builder;
builder.addAttachment(
builder.AddAttachment(
PassKey.DrawBufferFormat, (VkSampleCountFlagBits)PassKey.Samples,
(clearTargets & CT_Color) ? VK_ATTACHMENT_LOAD_OP_CLEAR : VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE,
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
for (int i = 1; i < PassKey.DrawBuffers; i++)
{
builder.addAttachment(
builder.AddAttachment(
drawBufferFormats[i], buffers->GetSceneSamples(),
(clearTargets & CT_Color) ? VK_ATTACHMENT_LOAD_OP_CLEAR : VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE,
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
}
if (PassKey.DepthStencil)
{
builder.addDepthStencilAttachment(
builder.AddDepthStencilAttachment(
buffers->SceneDepthStencilFormat, PassKey.DrawBufferFormat == VK_FORMAT_R8G8B8A8_UNORM ? VK_SAMPLE_COUNT_1_BIT : buffers->GetSceneSamples(),
(clearTargets & CT_Depth) ? VK_ATTACHMENT_LOAD_OP_CLEAR : VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE,
(clearTargets & CT_Stencil) ? VK_ATTACHMENT_LOAD_OP_CLEAR : VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE,
VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
}
builder.addSubpass();
builder.AddSubpass();
for (int i = 0; i < PassKey.DrawBuffers; i++)
builder.addSubpassColorAttachmentRef(i, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
builder.AddSubpassColorAttachmentRef(i, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
if (PassKey.DepthStencil)
{
builder.addSubpassDepthStencilAttachmentRef(PassKey.DrawBuffers, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
builder.addExternalSubpassDependency(
builder.AddSubpassDepthStencilAttachmentRef(PassKey.DrawBuffers, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
builder.AddExternalSubpassDependency(
VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
@ -178,15 +178,14 @@ std::unique_ptr<VulkanRenderPass> VkRenderPassSetup::CreateRenderPass(int clearT
}
else
{
builder.addExternalSubpassDependency(
builder.AddExternalSubpassDependency(
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
VK_ACCESS_COLOR_ATTACHMENT_READ_BIT);
}
auto renderpass = builder.create(fb->device);
renderpass->SetDebugName("VkRenderPassSetup.RenderPass");
return renderpass;
builder.DebugName("VkRenderPassSetup.RenderPass");
return builder.Create(fb->device);
}
VulkanRenderPass *VkRenderPassSetup::GetRenderPass(int clearTargets)
@ -217,13 +216,13 @@ std::unique_ptr<VulkanPipeline> VkRenderPassSetup::CreatePipeline(const VkPipeli
{
program = fb->GetShaderManager()->Get(key.EffectState, key.AlphaTest, PassKey.DrawBuffers > 1 ? GBUFFER_PASS : NORMAL_PASS);
}
builder.addVertexShader(program->vert.get());
builder.addFragmentShader(program->frag.get());
builder.AddVertexShader(program->vert.get());
builder.AddFragmentShader(program->frag.get());
const VkVertexFormat &vfmt = *fb->GetRenderPassManager()->GetVertexFormat(key.VertexFormat);
for (int i = 0; i < vfmt.NumBindingPoints; i++)
builder.addVertexBufferBinding(i, vfmt.Stride);
builder.AddVertexBufferBinding(i, vfmt.Stride);
const static VkFormat vkfmts[] = {
VK_FORMAT_R32G32B32A32_SFLOAT,
@ -239,7 +238,7 @@ std::unique_ptr<VulkanPipeline> VkRenderPassSetup::CreatePipeline(const VkPipeli
for (size_t i = 0; i < vfmt.Attrs.size(); i++)
{
const auto &attr = vfmt.Attrs[i];
builder.addVertexAttribute(attr.location, attr.binding, vkfmts[attr.format], attr.offset);
builder.AddVertexAttribute(attr.location, attr.binding, vkfmts[attr.format], attr.offset);
inputLocations[attr.location] = true;
}
@ -247,17 +246,17 @@ std::unique_ptr<VulkanPipeline> VkRenderPassSetup::CreatePipeline(const VkPipeli
for (int i = 0; i < 7; i++)
{
if (!inputLocations[i])
builder.addVertexAttribute(i, 0, VK_FORMAT_R32G32B32_SFLOAT, 0);
builder.AddVertexAttribute(i, 0, VK_FORMAT_R32G32B32_SFLOAT, 0);
}
builder.addDynamicState(VK_DYNAMIC_STATE_VIEWPORT);
builder.addDynamicState(VK_DYNAMIC_STATE_SCISSOR);
builder.addDynamicState(VK_DYNAMIC_STATE_DEPTH_BIAS);
builder.addDynamicState(VK_DYNAMIC_STATE_STENCIL_REFERENCE);
builder.AddDynamicState(VK_DYNAMIC_STATE_VIEWPORT);
builder.AddDynamicState(VK_DYNAMIC_STATE_SCISSOR);
builder.AddDynamicState(VK_DYNAMIC_STATE_DEPTH_BIAS);
builder.AddDynamicState(VK_DYNAMIC_STATE_STENCIL_REFERENCE);
// Note: the actual values are ignored since we use dynamic viewport+scissor states
builder.setViewport(0.0f, 0.0f, 320.0f, 200.0f);
builder.setScissor(0, 0, 320, 200);
builder.Viewport(0.0f, 0.0f, 320.0f, 200.0f);
builder.Scissor(0, 0, 320, 200);
static const VkPrimitiveTopology vktopology[] = {
VK_PRIMITIVE_TOPOLOGY_POINT_LIST,
@ -270,28 +269,28 @@ std::unique_ptr<VulkanPipeline> VkRenderPassSetup::CreatePipeline(const VkPipeli
static const VkStencilOp op2vk[] = { VK_STENCIL_OP_KEEP, VK_STENCIL_OP_INCREMENT_AND_CLAMP, VK_STENCIL_OP_DECREMENT_AND_CLAMP };
static const VkCompareOp depthfunc2vk[] = { VK_COMPARE_OP_LESS, VK_COMPARE_OP_LESS_OR_EQUAL, VK_COMPARE_OP_ALWAYS };
builder.setTopology(vktopology[key.DrawType]);
builder.setDepthStencilEnable(key.DepthTest, key.DepthWrite, key.StencilTest);
builder.setDepthFunc(depthfunc2vk[key.DepthFunc]);
builder.Topology(vktopology[key.DrawType]);
builder.DepthStencilEnable(key.DepthTest, key.DepthWrite, key.StencilTest);
builder.DepthFunc(depthfunc2vk[key.DepthFunc]);
if (fb->device->UsedDeviceFeatures.depthClamp)
builder.setDepthClampEnable(key.DepthClamp);
builder.setDepthBias(key.DepthBias, 0.0f, 0.0f, 0.0f);
builder.DepthClampEnable(key.DepthClamp);
builder.DepthBias(key.DepthBias, 0.0f, 0.0f, 0.0f);
// Note: CCW and CW is intentionally swapped here because the vulkan and opengl coordinate systems differ.
// main.vp addresses this by patching up gl_Position.z, which has the side effect of flipping the sign of the front face calculations.
builder.setCull(key.CullMode == Cull_None ? VK_CULL_MODE_NONE : VK_CULL_MODE_BACK_BIT, key.CullMode == Cull_CW ? VK_FRONT_FACE_COUNTER_CLOCKWISE : VK_FRONT_FACE_CLOCKWISE);
builder.Cull(key.CullMode == Cull_None ? VK_CULL_MODE_NONE : VK_CULL_MODE_BACK_BIT, key.CullMode == Cull_CW ? VK_FRONT_FACE_COUNTER_CLOCKWISE : VK_FRONT_FACE_CLOCKWISE);
builder.setColorWriteMask((VkColorComponentFlags)key.ColorMask);
builder.setStencil(VK_STENCIL_OP_KEEP, op2vk[key.StencilPassOp], VK_STENCIL_OP_KEEP, VK_COMPARE_OP_EQUAL, 0xffffffff, 0xffffffff, 0);
builder.setBlendMode(key.RenderStyle);
builder.setSubpassColorAttachmentCount(PassKey.DrawBuffers);
builder.setRasterizationSamples((VkSampleCountFlagBits)PassKey.Samples);
builder.ColorWriteMask((VkColorComponentFlags)key.ColorMask);
builder.Stencil(VK_STENCIL_OP_KEEP, op2vk[key.StencilPassOp], VK_STENCIL_OP_KEEP, VK_COMPARE_OP_EQUAL, 0xffffffff, 0xffffffff, 0);
builder.BlendMode(key.RenderStyle);
builder.SubpassColorAttachmentCount(PassKey.DrawBuffers);
builder.RasterizationSamples((VkSampleCountFlagBits)PassKey.Samples);
builder.setLayout(fb->GetRenderPassManager()->GetPipelineLayout(key.NumTextureLayers));
builder.setRenderPass(GetRenderPass(0));
auto pipeline = builder.create(fb->device);
pipeline->SetDebugName("VkRenderPassSetup.Pipeline");
return pipeline;
builder.Layout(fb->GetRenderPassManager()->GetPipelineLayout(key.NumTextureLayers));
builder.RenderPass(GetRenderPass(0));
builder.DebugName("VkRenderPassSetup.Pipeline");
return builder.Create(fb->device);
}
/////////////////////////////////////////////////////////////////////////////
@ -308,78 +307,78 @@ void VkPPRenderPassSetup::CreateDescriptorLayout(const VkPPRenderPassKey& key)
{
DescriptorSetLayoutBuilder builder;
for (int i = 0; i < key.InputTextures; i++)
builder.addBinding(i, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT);
builder.AddBinding(i, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT);
if (key.ShadowMapBuffers)
{
builder.addBinding(LIGHTNODES_BINDINGPOINT, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT);
builder.addBinding(LIGHTLINES_BINDINGPOINT, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT);
builder.addBinding(LIGHTLIST_BINDINGPOINT, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT);
builder.AddBinding(LIGHTNODES_BINDINGPOINT, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT);
builder.AddBinding(LIGHTLINES_BINDINGPOINT, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT);
builder.AddBinding(LIGHTLIST_BINDINGPOINT, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT);
}
DescriptorLayout = builder.create(fb->device);
DescriptorLayout->SetDebugName("VkPPRenderPassSetup.DescriptorLayout");
builder.DebugName("VkPPRenderPassSetup.DescriptorLayout");
DescriptorLayout = builder.Create(fb->device);
}
void VkPPRenderPassSetup::CreatePipelineLayout(const VkPPRenderPassKey& key)
{
PipelineLayoutBuilder builder;
builder.addSetLayout(DescriptorLayout.get());
builder.AddSetLayout(DescriptorLayout.get());
if (key.Uniforms > 0)
builder.addPushConstantRange(VK_SHADER_STAGE_FRAGMENT_BIT, 0, key.Uniforms);
PipelineLayout = builder.create(fb->device);
PipelineLayout->SetDebugName("VkPPRenderPassSetup.PipelineLayout");
builder.AddPushConstantRange(VK_SHADER_STAGE_FRAGMENT_BIT, 0, key.Uniforms);
builder.DebugName("VkPPRenderPassSetup.PipelineLayout");
PipelineLayout = builder.Create(fb->device);
}
void VkPPRenderPassSetup::CreatePipeline(const VkPPRenderPassKey& key)
{
GraphicsPipelineBuilder builder;
builder.addVertexShader(key.Shader->VertexShader.get());
builder.addFragmentShader(key.Shader->FragmentShader.get());
builder.AddVertexShader(key.Shader->VertexShader.get());
builder.AddFragmentShader(key.Shader->FragmentShader.get());
builder.addVertexBufferBinding(0, sizeof(FFlatVertex));
builder.addVertexAttribute(0, 0, VK_FORMAT_R32G32B32_SFLOAT, offsetof(FFlatVertex, x));
builder.addVertexAttribute(1, 0, VK_FORMAT_R32G32_SFLOAT, offsetof(FFlatVertex, u));
builder.addDynamicState(VK_DYNAMIC_STATE_VIEWPORT);
builder.addDynamicState(VK_DYNAMIC_STATE_SCISSOR);
builder.AddVertexBufferBinding(0, sizeof(FFlatVertex));
builder.AddVertexAttribute(0, 0, VK_FORMAT_R32G32B32_SFLOAT, offsetof(FFlatVertex, x));
builder.AddVertexAttribute(1, 0, VK_FORMAT_R32G32_SFLOAT, offsetof(FFlatVertex, u));
builder.AddDynamicState(VK_DYNAMIC_STATE_VIEWPORT);
builder.AddDynamicState(VK_DYNAMIC_STATE_SCISSOR);
// Note: the actual values are ignored since we use dynamic viewport+scissor states
builder.setViewport(0.0f, 0.0f, 320.0f, 200.0f);
builder.setScissor(0, 0, 320, 200);
builder.Viewport(0.0f, 0.0f, 320.0f, 200.0f);
builder.Scissor(0, 0, 320, 200);
if (key.StencilTest)
{
builder.addDynamicState(VK_DYNAMIC_STATE_STENCIL_REFERENCE);
builder.setDepthStencilEnable(false, false, true);
builder.setStencil(VK_STENCIL_OP_KEEP, VK_STENCIL_OP_KEEP, VK_STENCIL_OP_KEEP, VK_COMPARE_OP_EQUAL, 0xffffffff, 0xffffffff, 0);
builder.AddDynamicState(VK_DYNAMIC_STATE_STENCIL_REFERENCE);
builder.DepthStencilEnable(false, false, true);
builder.Stencil(VK_STENCIL_OP_KEEP, VK_STENCIL_OP_KEEP, VK_STENCIL_OP_KEEP, VK_COMPARE_OP_EQUAL, 0xffffffff, 0xffffffff, 0);
}
builder.setTopology(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP);
builder.setBlendMode(key.BlendMode);
builder.setRasterizationSamples(key.Samples);
builder.setLayout(PipelineLayout.get());
builder.setRenderPass(RenderPass.get());
Pipeline = builder.create(fb->device);
Pipeline->SetDebugName("VkPPRenderPassSetup.Pipeline");
builder.Topology(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP);
builder.BlendMode(key.BlendMode);
builder.RasterizationSamples(key.Samples);
builder.Layout(PipelineLayout.get());
builder.RenderPass(RenderPass.get());
builder.DebugName("VkPPRenderPassSetup.Pipeline");
Pipeline = builder.Create(fb->device);
}
void VkPPRenderPassSetup::CreateRenderPass(const VkPPRenderPassKey& key)
{
RenderPassBuilder builder;
if (key.SwapChain)
builder.addAttachment(key.OutputFormat, key.Samples, VK_ATTACHMENT_LOAD_OP_CLEAR, VK_ATTACHMENT_STORE_OP_STORE, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_PRESENT_SRC_KHR);
builder.AddAttachment(key.OutputFormat, key.Samples, VK_ATTACHMENT_LOAD_OP_CLEAR, VK_ATTACHMENT_STORE_OP_STORE, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_PRESENT_SRC_KHR);
else
builder.addAttachment(key.OutputFormat, key.Samples, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
builder.AddAttachment(key.OutputFormat, key.Samples, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
if (key.StencilTest)
{
builder.addDepthStencilAttachment(
builder.AddDepthStencilAttachment(
fb->GetBuffers()->SceneDepthStencilFormat, key.Samples,
VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE,
VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE,
VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
}
builder.addSubpass();
builder.addSubpassColorAttachmentRef(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
builder.AddSubpass();
builder.AddSubpassColorAttachmentRef(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
if (key.StencilTest)
{
builder.addSubpassDepthStencilAttachmentRef(1, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
builder.addExternalSubpassDependency(
builder.AddSubpassDepthStencilAttachmentRef(1, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
builder.AddExternalSubpassDependency(
VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
@ -387,13 +386,13 @@ void VkPPRenderPassSetup::CreateRenderPass(const VkPPRenderPassKey& key)
}
else
{
builder.addExternalSubpassDependency(
builder.AddExternalSubpassDependency(
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_SHADER_READ_BIT);
}
RenderPass = builder.create(fb->device);
RenderPass->SetDebugName("VkPPRenderPassSetup.RenderPass");
builder.DebugName("VkPPRenderPassSetup.RenderPass");
RenderPass = builder.Create(fb->device);
}

View file

@ -544,17 +544,17 @@ void VkRenderState::BeginRenderPass(VulkanCommandBuffer *cmdbuffer)
{
auto buffers = fb->GetBuffers();
FramebufferBuilder builder;
builder.setRenderPass(mPassSetup->GetRenderPass(0));
builder.setSize(mRenderTarget.Width, mRenderTarget.Height);
builder.addAttachment(mRenderTarget.Image->View.get());
builder.RenderPass(mPassSetup->GetRenderPass(0));
builder.Size(mRenderTarget.Width, mRenderTarget.Height);
builder.AddAttachment(mRenderTarget.Image->View.get());
if (key.DrawBuffers > 1)
builder.addAttachment(buffers->SceneFog.View.get());
builder.AddAttachment(buffers->SceneFog.View.get());
if (key.DrawBuffers > 2)
builder.addAttachment(buffers->SceneNormal.View.get());
builder.AddAttachment(buffers->SceneNormal.View.get());
if (key.DepthStencil)
builder.addAttachment(mRenderTarget.DepthStencil);
framebuffer = builder.create(fb->device);
framebuffer->SetDebugName("VkRenderPassSetup.Framebuffer");
builder.AddAttachment(mRenderTarget.DepthStencil);
builder.DebugName("VkRenderPassSetup.Framebuffer");
framebuffer = builder.Create(fb->device);
}
// Only clear depth+stencil if the render target actually has that

View file

@ -34,15 +34,15 @@ VkPPShader::VkPPShader(VulkanFrameBuffer* fb, PPShader *shader) : fb(fb)
prolog = UniformBlockDecl::Create("Uniforms", shader->Uniforms, -1);
prolog += shader->Defines;
ShaderBuilder vertbuilder;
vertbuilder.setVertexShader(LoadShaderCode(shader->VertexShader, "", shader->Version));
VertexShader = vertbuilder.create(shader->VertexShader.GetChars(), fb->device);
VertexShader->SetDebugName(shader->VertexShader.GetChars());
VertexShader = ShaderBuilder()
.VertexShader(LoadShaderCode(shader->VertexShader, "", shader->Version))
.DebugName(shader->VertexShader.GetChars())
.Create(shader->VertexShader.GetChars(), fb->device);
ShaderBuilder fragbuilder;
fragbuilder.setFragmentShader(LoadShaderCode(shader->FragmentShader, prolog, shader->Version));
FragmentShader = fragbuilder.create(shader->FragmentShader.GetChars(), fb->device);
FragmentShader->SetDebugName(shader->FragmentShader.GetChars());
FragmentShader = ShaderBuilder()
.FragmentShader(LoadShaderCode(shader->FragmentShader, prolog, shader->Version))
.DebugName(shader->FragmentShader.GetChars())
.Create(shader->FragmentShader.GetChars(), fb->device);
fb->GetShaderManager()->AddVkPPShader(this);
}

View file

@ -341,11 +341,10 @@ std::unique_ptr<VulkanShader> VkShaderManager::LoadVertShader(FString shadername
code << "#line 1\n";
code << LoadPrivateShaderLump(vert_lump).GetChars() << "\n";
ShaderBuilder builder;
builder.setVertexShader(code);
auto shader = builder.create(shadername.GetChars(), fb->device);
shader->SetDebugName(shadername.GetChars());
return shader;
return ShaderBuilder()
.VertexShader(code)
.DebugName(shadername.GetChars())
.Create(shadername.GetChars(), fb->device);
}
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)
@ -434,11 +433,10 @@ std::unique_ptr<VulkanShader> VkShaderManager::LoadFragShader(FString shadername
code << LoadPrivateShaderLump(light_lump).GetChars();
}
ShaderBuilder builder;
builder.setFragmentShader(code);
auto shader = builder.create(shadername.GetChars(), fb->device);
shader->SetDebugName(shadername.GetChars());
return shader;
return ShaderBuilder()
.FragmentShader(code)
.DebugName(shadername.GetChars())
.Create(shadername.GetChars(), fb->device);
}
FString VkShaderManager::GetTargetGlslVersion()

View file

@ -138,19 +138,21 @@ ShaderBuilder::ShaderBuilder()
{
}
void ShaderBuilder::setVertexShader(const FString &c)
ShaderBuilder& ShaderBuilder::VertexShader(const FString &c)
{
code = c;
stage = EShLanguage::EShLangVertex;
return *this;
}
void ShaderBuilder::setFragmentShader(const FString &c)
ShaderBuilder& ShaderBuilder::FragmentShader(const FString &c)
{
code = c;
stage = EShLanguage::EShLangFragment;
return *this;
}
std::unique_ptr<VulkanShader> ShaderBuilder::create(const char *shadername, VulkanDevice *device)
std::unique_ptr<VulkanShader> ShaderBuilder::Create(const char *shadername, VulkanDevice *device)
{
EShLanguage stage = (EShLanguage)this->stage;
const char *sources[] = { code.GetChars() };
@ -213,18 +215,21 @@ std::unique_ptr<VulkanShader> ShaderBuilder::create(const char *shadername, Vulk
VulkanError(msg.GetChars());
}
return std::make_unique<VulkanShader>(device, shaderModule);
auto obj = std::make_unique<VulkanShader>(device, shaderModule);
if (debugName)
obj->SetDebugName(debugName);
return obj;
}
/////////////////////////////////////////////////////////////////////////////
void GraphicsPipelineBuilder::setBlendMode(const FRenderStyle &style)
GraphicsPipelineBuilder& GraphicsPipelineBuilder::BlendMode(const FRenderStyle &style)
{
// Just in case Vulkan doesn't do this optimization itself
if (style.BlendOp == STYLEOP_Add && style.SrcAlpha == STYLEALPHA_One && style.DestAlpha == STYLEALPHA_Zero && style.Flags == 0)
{
colorBlendAttachment.blendEnable = VK_FALSE;
return;
return *this;
}
static const int blendstyles[] = {
@ -255,7 +260,7 @@ void GraphicsPipelineBuilder::setBlendMode(const FRenderStyle &style)
blendequation = VK_BLEND_OP_ADD;
}
setBlendMode((VkBlendOp)blendequation, (VkBlendFactor)srcblend, (VkBlendFactor)dstblend);
BlendMode((VkBlendOp)blendequation, (VkBlendFactor)srcblend, (VkBlendFactor)dstblend);
}
/////////////////////////////////////////////////////////////////////////////
@ -273,44 +278,50 @@ ImageBuilder::ImageBuilder()
imageInfo.flags = 0;
}
void ImageBuilder::setSize(int width, int height, int mipLevels, int arrayLayers)
ImageBuilder& ImageBuilder::Size(int width, int height, int mipLevels, int arrayLayers)
{
imageInfo.extent.width = width;
imageInfo.extent.height = height;
imageInfo.mipLevels = mipLevels;
imageInfo.arrayLayers = arrayLayers;
return *this;
}
void ImageBuilder::setSamples(VkSampleCountFlagBits samples)
ImageBuilder& ImageBuilder::Samples(VkSampleCountFlagBits samples)
{
imageInfo.samples = samples;
return *this;
}
void ImageBuilder::setFormat(VkFormat format)
ImageBuilder& ImageBuilder::Format(VkFormat format)
{
imageInfo.format = format;
return *this;
}
void ImageBuilder::setLinearTiling()
ImageBuilder& ImageBuilder::LinearTiling()
{
imageInfo.tiling = VK_IMAGE_TILING_LINEAR;
return *this;
}
void ImageBuilder::setUsage(VkImageUsageFlags usage, VmaMemoryUsage memoryUsage, VmaAllocationCreateFlags allocFlags)
ImageBuilder& ImageBuilder::Usage(VkImageUsageFlags usage, VmaMemoryUsage memoryUsage, VmaAllocationCreateFlags allocFlags)
{
imageInfo.usage = usage;
allocInfo.usage = memoryUsage;
allocInfo.flags = allocFlags;
return *this;
}
void ImageBuilder::setMemoryType(VkMemoryPropertyFlags requiredFlags, VkMemoryPropertyFlags preferredFlags, uint32_t memoryTypeBits)
ImageBuilder& ImageBuilder::MemoryType(VkMemoryPropertyFlags requiredFlags, VkMemoryPropertyFlags preferredFlags, uint32_t memoryTypeBits)
{
allocInfo.requiredFlags = requiredFlags;
allocInfo.preferredFlags = preferredFlags;
allocInfo.memoryTypeBits = memoryTypeBits;
return *this;
}
bool ImageBuilder::isFormatSupported(VulkanDevice* device, VkFormatFeatureFlags bufferFeatures)
bool ImageBuilder::IsFormatSupported(VulkanDevice* device, VkFormatFeatureFlags bufferFeatures)
{
VkImageFormatProperties properties = { };
VkResult result = vkGetPhysicalDeviceImageFormatProperties(device->PhysicalDevice.Device, imageInfo.format, imageInfo.imageType, imageInfo.tiling, imageInfo.usage, imageInfo.flags, &properties);
@ -331,7 +342,7 @@ bool ImageBuilder::isFormatSupported(VulkanDevice* device, VkFormatFeatureFlags
return true;
}
std::unique_ptr<VulkanImage> ImageBuilder::create(VulkanDevice* device, VkDeviceSize* allocatedBytes)
std::unique_ptr<VulkanImage> ImageBuilder::Create(VulkanDevice* device, VkDeviceSize* allocatedBytes)
{
VkImage image;
VmaAllocation allocation;
@ -347,10 +358,13 @@ std::unique_ptr<VulkanImage> ImageBuilder::create(VulkanDevice* device, VkDevice
*allocatedBytes = allocatedInfo.size;
}
return std::make_unique<VulkanImage>(device, image, allocation, imageInfo.extent.width, imageInfo.extent.height, imageInfo.mipLevels, imageInfo.arrayLayers);
auto obj = std::make_unique<VulkanImage>(device, image, allocation, imageInfo.extent.width, imageInfo.extent.height, imageInfo.mipLevels, imageInfo.arrayLayers);
if (debugName)
obj->SetDebugName(debugName);
return obj;
}
std::unique_ptr<VulkanImage> ImageBuilder::tryCreate(VulkanDevice* device)
std::unique_ptr<VulkanImage> ImageBuilder::TryCreate(VulkanDevice* device)
{
VkImage image;
VmaAllocation allocation;
@ -359,7 +373,10 @@ std::unique_ptr<VulkanImage> ImageBuilder::tryCreate(VulkanDevice* device)
if (result != VK_SUCCESS)
return nullptr;
return std::make_unique<VulkanImage>(device, image, allocation, imageInfo.extent.width, imageInfo.extent.height, imageInfo.mipLevels, imageInfo.arrayLayers);
auto obj = std::make_unique<VulkanImage>(device, image, allocation, imageInfo.extent.width, imageInfo.extent.height, imageInfo.mipLevels, imageInfo.arrayLayers);
if (debugName)
obj->SetDebugName(debugName);
return obj;
}
/////////////////////////////////////////////////////////////////////////////
@ -374,27 +391,32 @@ ImageViewBuilder::ImageViewBuilder()
viewInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
}
void ImageViewBuilder::setType(VkImageViewType type)
ImageViewBuilder& ImageViewBuilder::Type(VkImageViewType type)
{
viewInfo.viewType = type;
return *this;
}
void ImageViewBuilder::setImage(VulkanImage* image, VkFormat format, VkImageAspectFlags aspectMask)
ImageViewBuilder& ImageViewBuilder::Image(VulkanImage* image, VkFormat format, VkImageAspectFlags aspectMask)
{
viewInfo.image = image->image;
viewInfo.format = format;
viewInfo.subresourceRange.levelCount = image->mipLevels;
viewInfo.subresourceRange.aspectMask = aspectMask;
viewInfo.subresourceRange.layerCount = image->layerCount;
return *this;
}
std::unique_ptr<VulkanImageView> ImageViewBuilder::create(VulkanDevice* device)
std::unique_ptr<VulkanImageView> ImageViewBuilder::Create(VulkanDevice* device)
{
VkImageView view;
VkResult result = vkCreateImageView(device->device, &viewInfo, nullptr, &view);
CheckVulkanError(result, "Could not create texture image view");
return std::make_unique<VulkanImageView>(device, view);
auto obj = std::make_unique<VulkanImageView>(device, view);
if (debugName)
obj->SetDebugName(debugName);
return obj;
}
/////////////////////////////////////////////////////////////////////////////
@ -419,52 +441,62 @@ SamplerBuilder::SamplerBuilder()
samplerInfo.maxLod = 100.0f;
}
void SamplerBuilder::setAddressMode(VkSamplerAddressMode addressMode)
SamplerBuilder& SamplerBuilder::AddressMode(VkSamplerAddressMode addressMode)
{
samplerInfo.addressModeU = addressMode;
samplerInfo.addressModeV = addressMode;
samplerInfo.addressModeW = addressMode;
return *this;
}
void SamplerBuilder::setAddressMode(VkSamplerAddressMode u, VkSamplerAddressMode v, VkSamplerAddressMode w)
SamplerBuilder& SamplerBuilder::AddressMode(VkSamplerAddressMode u, VkSamplerAddressMode v, VkSamplerAddressMode w)
{
samplerInfo.addressModeU = u;
samplerInfo.addressModeV = v;
samplerInfo.addressModeW = w;
return *this;
}
void SamplerBuilder::setMinFilter(VkFilter minFilter)
SamplerBuilder& SamplerBuilder::MinFilter(VkFilter minFilter)
{
samplerInfo.minFilter = minFilter;
return *this;
}
void SamplerBuilder::setMagFilter(VkFilter magFilter)
SamplerBuilder& SamplerBuilder::MagFilter(VkFilter magFilter)
{
samplerInfo.magFilter = magFilter;
return *this;
}
void SamplerBuilder::setMipmapMode(VkSamplerMipmapMode mode)
SamplerBuilder& SamplerBuilder::MipmapMode(VkSamplerMipmapMode mode)
{
samplerInfo.mipmapMode = mode;
return *this;
}
void SamplerBuilder::setAnisotropy(float maxAnisotropy)
SamplerBuilder& SamplerBuilder::Anisotropy(float maxAnisotropy)
{
samplerInfo.anisotropyEnable = VK_TRUE;
samplerInfo.maxAnisotropy = maxAnisotropy;
return *this;
}
void SamplerBuilder::setMaxLod(float value)
SamplerBuilder& SamplerBuilder::MaxLod(float value)
{
samplerInfo.maxLod = value;
return *this;
}
std::unique_ptr<VulkanSampler> SamplerBuilder::create(VulkanDevice* device)
std::unique_ptr<VulkanSampler> SamplerBuilder::Create(VulkanDevice* device)
{
VkSampler sampler;
VkResult result = vkCreateSampler(device->device, &samplerInfo, nullptr, &sampler);
CheckVulkanError(result, "Could not create texture sampler");
return std::make_unique<VulkanSampler>(device, sampler);
auto obj = std::make_unique<VulkanSampler>(device, sampler);
if (debugName)
obj->SetDebugName(debugName);
return obj;
}
/////////////////////////////////////////////////////////////////////////////
@ -475,26 +507,29 @@ BufferBuilder::BufferBuilder()
bufferInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
}
void BufferBuilder::setSize(size_t size)
BufferBuilder& BufferBuilder::Size(size_t size)
{
bufferInfo.size = max(size, (size_t)16);
return *this;
}
void BufferBuilder::setUsage(VkBufferUsageFlags bufferUsage, VmaMemoryUsage memoryUsage, VmaAllocationCreateFlags allocFlags)
BufferBuilder& BufferBuilder::Usage(VkBufferUsageFlags bufferUsage, VmaMemoryUsage memoryUsage, VmaAllocationCreateFlags allocFlags)
{
bufferInfo.usage = bufferUsage;
allocInfo.usage = memoryUsage;
allocInfo.flags = allocFlags;
return *this;
}
void BufferBuilder::setMemoryType(VkMemoryPropertyFlags requiredFlags, VkMemoryPropertyFlags preferredFlags, uint32_t memoryTypeBits)
BufferBuilder& BufferBuilder::MemoryType(VkMemoryPropertyFlags requiredFlags, VkMemoryPropertyFlags preferredFlags, uint32_t memoryTypeBits)
{
allocInfo.requiredFlags = requiredFlags;
allocInfo.preferredFlags = preferredFlags;
allocInfo.memoryTypeBits = memoryTypeBits;
return *this;
}
std::unique_ptr<VulkanBuffer> BufferBuilder::create(VulkanDevice* device)
std::unique_ptr<VulkanBuffer> BufferBuilder::Create(VulkanDevice* device)
{
VkBuffer buffer;
VmaAllocation allocation;
@ -502,7 +537,10 @@ std::unique_ptr<VulkanBuffer> BufferBuilder::create(VulkanDevice* device)
VkResult result = vmaCreateBuffer(device->allocator, &bufferInfo, &allocInfo, &buffer, &allocation, nullptr);
CheckVulkanError(result, "Could not allocate memory for vulkan buffer");
return std::make_unique<VulkanBuffer>(device, buffer, allocation, bufferInfo.size);
auto obj = std::make_unique<VulkanBuffer>(device, buffer, allocation, bufferInfo.size);
if (debugName)
obj->SetDebugName(debugName);
return obj;
}
/////////////////////////////////////////////////////////////////////////////
@ -513,25 +551,30 @@ ComputePipelineBuilder::ComputePipelineBuilder()
stageInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
}
void ComputePipelineBuilder::setLayout(VulkanPipelineLayout* layout)
ComputePipelineBuilder& ComputePipelineBuilder::Layout(VulkanPipelineLayout* layout)
{
pipelineInfo.layout = layout->layout;
return *this;
}
void ComputePipelineBuilder::setComputeShader(VulkanShader* shader)
ComputePipelineBuilder& ComputePipelineBuilder::ComputeShader(VulkanShader* shader)
{
stageInfo.stage = VK_SHADER_STAGE_COMPUTE_BIT;
stageInfo.module = shader->module;
stageInfo.pName = "main";
pipelineInfo.stage = stageInfo;
return *this;
}
std::unique_ptr<VulkanPipeline> ComputePipelineBuilder::create(VulkanDevice* device)
std::unique_ptr<VulkanPipeline> ComputePipelineBuilder::Create(VulkanDevice* device)
{
VkPipeline pipeline;
vkCreateComputePipelines(device->device, VK_NULL_HANDLE, 1, &pipelineInfo, nullptr, &pipeline);
return std::make_unique<VulkanPipeline>(device, pipeline);
auto obj = std::make_unique<VulkanPipeline>(device, pipeline);
if (debugName)
obj->SetDebugName(debugName);
return obj;
}
/////////////////////////////////////////////////////////////////////////////
@ -541,7 +584,7 @@ DescriptorSetLayoutBuilder::DescriptorSetLayoutBuilder()
layoutInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
}
void DescriptorSetLayoutBuilder::addBinding(int index, VkDescriptorType type, int arrayCount, VkShaderStageFlags stageFlags)
DescriptorSetLayoutBuilder& DescriptorSetLayoutBuilder::AddBinding(int index, VkDescriptorType type, int arrayCount, VkShaderStageFlags stageFlags)
{
VkDescriptorSetLayoutBinding binding = { };
binding.binding = index;
@ -553,14 +596,18 @@ void DescriptorSetLayoutBuilder::addBinding(int index, VkDescriptorType type, in
layoutInfo.bindingCount = (uint32_t)bindings.Size();
layoutInfo.pBindings = &bindings[0];
return *this;
}
std::unique_ptr<VulkanDescriptorSetLayout> DescriptorSetLayoutBuilder::create(VulkanDevice* device)
std::unique_ptr<VulkanDescriptorSetLayout> DescriptorSetLayoutBuilder::Create(VulkanDevice* device)
{
VkDescriptorSetLayout layout;
VkResult result = vkCreateDescriptorSetLayout(device->device, &layoutInfo, nullptr, &layout);
CheckVulkanError(result, "Could not create descriptor set layout");
return std::make_unique<VulkanDescriptorSetLayout>(device, layout);
auto obj = std::make_unique<VulkanDescriptorSetLayout>(device, layout);
if (debugName)
obj->SetDebugName(debugName);
return obj;
}
/////////////////////////////////////////////////////////////////////////////
@ -572,12 +619,13 @@ DescriptorPoolBuilder::DescriptorPoolBuilder()
poolInfo.flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT;
}
void DescriptorPoolBuilder::setMaxSets(int value)
DescriptorPoolBuilder& DescriptorPoolBuilder::MaxSets(int value)
{
poolInfo.maxSets = value;
return *this;
}
void DescriptorPoolBuilder::addPoolSize(VkDescriptorType type, int count)
DescriptorPoolBuilder& DescriptorPoolBuilder::AddPoolSize(VkDescriptorType type, int count)
{
VkDescriptorPoolSize size;
size.type = type;
@ -586,14 +634,18 @@ void DescriptorPoolBuilder::addPoolSize(VkDescriptorType type, int count)
poolInfo.poolSizeCount = (uint32_t)poolSizes.size();
poolInfo.pPoolSizes = poolSizes.data();
return *this;
}
std::unique_ptr<VulkanDescriptorPool> DescriptorPoolBuilder::create(VulkanDevice* device)
std::unique_ptr<VulkanDescriptorPool> DescriptorPoolBuilder::Create(VulkanDevice* device)
{
VkDescriptorPool descriptorPool;
VkResult result = vkCreateDescriptorPool(device->device, &poolInfo, nullptr, &descriptorPool);
CheckVulkanError(result, "Could not create descriptor pool");
return std::make_unique<VulkanDescriptorPool>(device, descriptorPool);
auto obj = std::make_unique<VulkanDescriptorPool>(device, descriptorPool);
if (debugName)
obj->SetDebugName(debugName);
return obj;
}
/////////////////////////////////////////////////////////////////////////////
@ -603,19 +655,23 @@ QueryPoolBuilder::QueryPoolBuilder()
poolInfo.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO;
}
void QueryPoolBuilder::setQueryType(VkQueryType type, int count, VkQueryPipelineStatisticFlags pipelineStatistics)
QueryPoolBuilder& QueryPoolBuilder::QueryType(VkQueryType type, int count, VkQueryPipelineStatisticFlags pipelineStatistics)
{
poolInfo.queryType = type;
poolInfo.queryCount = count;
poolInfo.pipelineStatistics = pipelineStatistics;
return *this;
}
std::unique_ptr<VulkanQueryPool> QueryPoolBuilder::create(VulkanDevice* device)
std::unique_ptr<VulkanQueryPool> QueryPoolBuilder::Create(VulkanDevice* device)
{
VkQueryPool queryPool;
VkResult result = vkCreateQueryPool(device->device, &poolInfo, nullptr, &queryPool);
CheckVulkanError(result, "Could not create query pool");
return std::make_unique<VulkanQueryPool>(device, queryPool);
auto obj = std::make_unique<VulkanQueryPool>(device, queryPool);
if (debugName)
obj->SetDebugName(debugName);
return obj;
}
/////////////////////////////////////////////////////////////////////////////
@ -625,40 +681,47 @@ FramebufferBuilder::FramebufferBuilder()
framebufferInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
}
void FramebufferBuilder::setRenderPass(VulkanRenderPass* renderPass)
FramebufferBuilder& FramebufferBuilder::RenderPass(VulkanRenderPass* renderPass)
{
framebufferInfo.renderPass = renderPass->renderPass;
return *this;
}
void FramebufferBuilder::addAttachment(VulkanImageView* view)
FramebufferBuilder& FramebufferBuilder::AddAttachment(VulkanImageView* view)
{
attachments.push_back(view->view);
framebufferInfo.attachmentCount = (uint32_t)attachments.size();
framebufferInfo.pAttachments = attachments.data();
return *this;
}
void FramebufferBuilder::addAttachment(VkImageView view)
FramebufferBuilder& FramebufferBuilder::AddAttachment(VkImageView view)
{
attachments.push_back(view);
framebufferInfo.attachmentCount = (uint32_t)attachments.size();
framebufferInfo.pAttachments = attachments.data();
return *this;
}
void FramebufferBuilder::setSize(int width, int height, int layers)
FramebufferBuilder& FramebufferBuilder::Size(int width, int height, int layers)
{
framebufferInfo.width = width;
framebufferInfo.height = height;
framebufferInfo.layers = 1;
return *this;
}
std::unique_ptr<VulkanFramebuffer> FramebufferBuilder::create(VulkanDevice* device)
std::unique_ptr<VulkanFramebuffer> FramebufferBuilder::Create(VulkanDevice* device)
{
VkFramebuffer framebuffer = 0;
VkResult result = vkCreateFramebuffer(device->device, &framebufferInfo, nullptr, &framebuffer);
CheckVulkanError(result, "Could not create framebuffer");
return std::make_unique<VulkanFramebuffer>(device, framebuffer);
auto obj = std::make_unique<VulkanFramebuffer>(device, framebuffer);
if (debugName)
obj->SetDebugName(debugName);
return obj;
}
/////////////////////////////////////////////////////////////////////////////
@ -741,32 +804,37 @@ GraphicsPipelineBuilder::GraphicsPipelineBuilder()
dynamicState.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
}
void GraphicsPipelineBuilder::setRasterizationSamples(VkSampleCountFlagBits samples)
GraphicsPipelineBuilder& GraphicsPipelineBuilder::RasterizationSamples(VkSampleCountFlagBits samples)
{
multisampling.rasterizationSamples = samples;
return *this;
}
void GraphicsPipelineBuilder::setSubpass(int subpass)
GraphicsPipelineBuilder& GraphicsPipelineBuilder::Subpass(int subpass)
{
pipelineInfo.subpass = subpass;
return *this;
}
void GraphicsPipelineBuilder::setLayout(VulkanPipelineLayout* layout)
GraphicsPipelineBuilder& GraphicsPipelineBuilder::Layout(VulkanPipelineLayout* layout)
{
pipelineInfo.layout = layout->layout;
return *this;
}
void GraphicsPipelineBuilder::setRenderPass(VulkanRenderPass* renderPass)
GraphicsPipelineBuilder& GraphicsPipelineBuilder::RenderPass(VulkanRenderPass* renderPass)
{
pipelineInfo.renderPass = renderPass->renderPass;
return *this;
}
void GraphicsPipelineBuilder::setTopology(VkPrimitiveTopology topology)
GraphicsPipelineBuilder& GraphicsPipelineBuilder::Topology(VkPrimitiveTopology topology)
{
inputAssembly.topology = topology;
return *this;
}
void GraphicsPipelineBuilder::setViewport(float x, float y, float width, float height, float minDepth, float maxDepth)
GraphicsPipelineBuilder& GraphicsPipelineBuilder::Viewport(float x, float y, float width, float height, float minDepth, float maxDepth)
{
viewport.x = 0.0f;
viewport.y = 0.0f;
@ -777,9 +845,10 @@ void GraphicsPipelineBuilder::setViewport(float x, float y, float width, float h
viewportState.viewportCount = 1;
viewportState.pViewports = &viewport;
return *this;
}
void GraphicsPipelineBuilder::setScissor(int x, int y, int width, int height)
GraphicsPipelineBuilder& GraphicsPipelineBuilder::Scissor(int x, int y, int width, int height)
{
scissor.offset.x = x;
scissor.offset.y = y;
@ -788,22 +857,25 @@ void GraphicsPipelineBuilder::setScissor(int x, int y, int width, int height)
viewportState.scissorCount = 1;
viewportState.pScissors = &scissor;
return *this;
}
void GraphicsPipelineBuilder::setCull(VkCullModeFlags cullMode, VkFrontFace frontFace)
GraphicsPipelineBuilder& GraphicsPipelineBuilder::Cull(VkCullModeFlags cullMode, VkFrontFace frontFace)
{
rasterizer.cullMode = cullMode;
rasterizer.frontFace = frontFace;
return *this;
}
void GraphicsPipelineBuilder::setDepthStencilEnable(bool test, bool write, bool stencil)
GraphicsPipelineBuilder& GraphicsPipelineBuilder::DepthStencilEnable(bool test, bool write, bool stencil)
{
depthStencil.depthTestEnable = test ? VK_TRUE : VK_FALSE;
depthStencil.depthWriteEnable = write ? VK_TRUE : VK_FALSE;
depthStencil.stencilTestEnable = stencil ? VK_TRUE : VK_FALSE;
return *this;
}
void GraphicsPipelineBuilder::setStencil(VkStencilOp failOp, VkStencilOp passOp, VkStencilOp depthFailOp, VkCompareOp compareOp, uint32_t compareMask, uint32_t writeMask, uint32_t reference)
GraphicsPipelineBuilder& GraphicsPipelineBuilder::Stencil(VkStencilOp failOp, VkStencilOp passOp, VkStencilOp depthFailOp, VkCompareOp compareOp, uint32_t compareMask, uint32_t writeMask, uint32_t reference)
{
depthStencil.front.failOp = failOp;
depthStencil.front.passOp = passOp;
@ -820,32 +892,37 @@ void GraphicsPipelineBuilder::setStencil(VkStencilOp failOp, VkStencilOp passOp,
depthStencil.back.compareMask = compareMask;
depthStencil.back.writeMask = writeMask;
depthStencil.back.reference = reference;
return *this;
}
void GraphicsPipelineBuilder::setDepthFunc(VkCompareOp func)
GraphicsPipelineBuilder& GraphicsPipelineBuilder::DepthFunc(VkCompareOp func)
{
depthStencil.depthCompareOp = func;
return *this;
}
void GraphicsPipelineBuilder::setDepthClampEnable(bool value)
GraphicsPipelineBuilder& GraphicsPipelineBuilder::DepthClampEnable(bool value)
{
rasterizer.depthClampEnable = value ? VK_TRUE : VK_FALSE;
return *this;
}
void GraphicsPipelineBuilder::setDepthBias(bool enable, float biasConstantFactor, float biasClamp, float biasSlopeFactor)
GraphicsPipelineBuilder& GraphicsPipelineBuilder::DepthBias(bool enable, float biasConstantFactor, float biasClamp, float biasSlopeFactor)
{
rasterizer.depthBiasEnable = enable ? VK_TRUE : VK_FALSE;
rasterizer.depthBiasConstantFactor = biasConstantFactor;
rasterizer.depthBiasClamp = biasClamp;
rasterizer.depthBiasSlopeFactor = biasSlopeFactor;
return *this;
}
void GraphicsPipelineBuilder::setColorWriteMask(VkColorComponentFlags mask)
GraphicsPipelineBuilder& GraphicsPipelineBuilder::ColorWriteMask(VkColorComponentFlags mask)
{
colorBlendAttachment.colorWriteMask = mask;
return *this;
}
void GraphicsPipelineBuilder::setAdditiveBlendMode()
GraphicsPipelineBuilder& GraphicsPipelineBuilder::AdditiveBlendMode()
{
colorBlendAttachment.blendEnable = VK_TRUE;
colorBlendAttachment.srcColorBlendFactor = VK_BLEND_FACTOR_ONE;
@ -854,9 +931,10 @@ void GraphicsPipelineBuilder::setAdditiveBlendMode()
colorBlendAttachment.srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE;
colorBlendAttachment.dstAlphaBlendFactor = VK_BLEND_FACTOR_ONE;
colorBlendAttachment.alphaBlendOp = VK_BLEND_OP_ADD;
return *this;
}
void GraphicsPipelineBuilder::setAlphaBlendMode()
GraphicsPipelineBuilder& GraphicsPipelineBuilder::AlphaBlendMode()
{
colorBlendAttachment.blendEnable = VK_TRUE;
colorBlendAttachment.srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA;
@ -865,9 +943,10 @@ void GraphicsPipelineBuilder::setAlphaBlendMode()
colorBlendAttachment.srcAlphaBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA;
colorBlendAttachment.dstAlphaBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
colorBlendAttachment.alphaBlendOp = VK_BLEND_OP_ADD;
return *this;
}
void GraphicsPipelineBuilder::setBlendMode(VkBlendOp op, VkBlendFactor src, VkBlendFactor dst)
GraphicsPipelineBuilder& GraphicsPipelineBuilder::BlendMode(VkBlendOp op, VkBlendFactor src, VkBlendFactor dst)
{
colorBlendAttachment.blendEnable = VK_TRUE;
colorBlendAttachment.srcColorBlendFactor = src;
@ -876,16 +955,18 @@ void GraphicsPipelineBuilder::setBlendMode(VkBlendOp op, VkBlendFactor src, VkBl
colorBlendAttachment.srcAlphaBlendFactor = src;
colorBlendAttachment.dstAlphaBlendFactor = dst;
colorBlendAttachment.alphaBlendOp = op;
return *this;
}
void GraphicsPipelineBuilder::setSubpassColorAttachmentCount(int count)
GraphicsPipelineBuilder& GraphicsPipelineBuilder::SubpassColorAttachmentCount(int count)
{
colorBlendAttachments.resize(count, colorBlendAttachment);
colorBlending.pAttachments = colorBlendAttachments.data();
colorBlending.attachmentCount = (uint32_t)colorBlendAttachments.size();
return *this;
}
void GraphicsPipelineBuilder::addVertexShader(VulkanShader* shader)
GraphicsPipelineBuilder& GraphicsPipelineBuilder::AddVertexShader(VulkanShader* shader)
{
VkPipelineShaderStageCreateInfo vertShaderStageInfo = {};
vertShaderStageInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
@ -896,9 +977,10 @@ void GraphicsPipelineBuilder::addVertexShader(VulkanShader* shader)
pipelineInfo.stageCount = (uint32_t)shaderStages.size();
pipelineInfo.pStages = shaderStages.data();
return *this;
}
void GraphicsPipelineBuilder::addFragmentShader(VulkanShader* shader)
GraphicsPipelineBuilder& GraphicsPipelineBuilder::AddFragmentShader(VulkanShader* shader)
{
VkPipelineShaderStageCreateInfo fragShaderStageInfo = {};
fragShaderStageInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
@ -909,9 +991,10 @@ void GraphicsPipelineBuilder::addFragmentShader(VulkanShader* shader)
pipelineInfo.stageCount = (uint32_t)shaderStages.size();
pipelineInfo.pStages = shaderStages.data();
return *this;
}
void GraphicsPipelineBuilder::addVertexBufferBinding(int index, size_t stride)
GraphicsPipelineBuilder& GraphicsPipelineBuilder::AddVertexBufferBinding(int index, size_t stride)
{
VkVertexInputBindingDescription desc = {};
desc.binding = index;
@ -921,9 +1004,10 @@ void GraphicsPipelineBuilder::addVertexBufferBinding(int index, size_t stride)
vertexInputInfo.vertexBindingDescriptionCount = (uint32_t)vertexInputBindings.size();
vertexInputInfo.pVertexBindingDescriptions = vertexInputBindings.data();
return *this;
}
void GraphicsPipelineBuilder::addVertexAttribute(int location, int binding, VkFormat format, size_t offset)
GraphicsPipelineBuilder& GraphicsPipelineBuilder::AddVertexAttribute(int location, int binding, VkFormat format, size_t offset)
{
VkVertexInputAttributeDescription desc = { };
desc.location = location;
@ -934,21 +1018,26 @@ void GraphicsPipelineBuilder::addVertexAttribute(int location, int binding, VkFo
vertexInputInfo.vertexAttributeDescriptionCount = (uint32_t)vertexInputAttributes.size();
vertexInputInfo.pVertexAttributeDescriptions = vertexInputAttributes.data();
return *this;
}
void GraphicsPipelineBuilder::addDynamicState(VkDynamicState state)
GraphicsPipelineBuilder& GraphicsPipelineBuilder::AddDynamicState(VkDynamicState state)
{
dynamicStates.push_back(state);
dynamicState.dynamicStateCount = (uint32_t)dynamicStates.size();
dynamicState.pDynamicStates = dynamicStates.data();
return *this;
}
std::unique_ptr<VulkanPipeline> GraphicsPipelineBuilder::create(VulkanDevice* device)
std::unique_ptr<VulkanPipeline> GraphicsPipelineBuilder::Create(VulkanDevice* device)
{
VkPipeline pipeline = 0;
VkResult result = vkCreateGraphicsPipelines(device->device, VK_NULL_HANDLE, 1, &pipelineInfo, nullptr, &pipeline);
CheckVulkanError(result, "Could not create graphics pipeline");
return std::make_unique<VulkanPipeline>(device, pipeline);
auto obj = std::make_unique<VulkanPipeline>(device, pipeline);
if (debugName)
obj->SetDebugName(debugName);
return obj;
}
/////////////////////////////////////////////////////////////////////////////
@ -958,14 +1047,15 @@ PipelineLayoutBuilder::PipelineLayoutBuilder()
pipelineLayoutInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
}
void PipelineLayoutBuilder::addSetLayout(VulkanDescriptorSetLayout* setLayout)
PipelineLayoutBuilder& PipelineLayoutBuilder::AddSetLayout(VulkanDescriptorSetLayout* setLayout)
{
setLayouts.push_back(setLayout->layout);
pipelineLayoutInfo.setLayoutCount = (uint32_t)setLayouts.size();
pipelineLayoutInfo.pSetLayouts = setLayouts.data();
return *this;
}
void PipelineLayoutBuilder::addPushConstantRange(VkShaderStageFlags stageFlags, size_t offset, size_t size)
PipelineLayoutBuilder& PipelineLayoutBuilder::AddPushConstantRange(VkShaderStageFlags stageFlags, size_t offset, size_t size)
{
VkPushConstantRange range = { };
range.stageFlags = stageFlags;
@ -974,14 +1064,18 @@ void PipelineLayoutBuilder::addPushConstantRange(VkShaderStageFlags stageFlags,
pushConstantRanges.push_back(range);
pipelineLayoutInfo.pushConstantRangeCount = (uint32_t)pushConstantRanges.size();
pipelineLayoutInfo.pPushConstantRanges = pushConstantRanges.data();
return *this;
}
std::unique_ptr<VulkanPipelineLayout> PipelineLayoutBuilder::create(VulkanDevice* device)
std::unique_ptr<VulkanPipelineLayout> PipelineLayoutBuilder::Create(VulkanDevice* device)
{
VkPipelineLayout pipelineLayout;
VkResult result = vkCreatePipelineLayout(device->device, &pipelineLayoutInfo, nullptr, &pipelineLayout);
CheckVulkanError(result, "Could not create pipeline layout");
return std::make_unique<VulkanPipelineLayout>(device, pipelineLayout);
auto obj = std::make_unique<VulkanPipelineLayout>(device, pipelineLayout);
if (debugName)
obj->SetDebugName(debugName);
return obj;
}
/////////////////////////////////////////////////////////////////////////////
@ -991,7 +1085,7 @@ RenderPassBuilder::RenderPassBuilder()
renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
}
void RenderPassBuilder::addAttachment(VkFormat format, VkSampleCountFlagBits samples, VkAttachmentLoadOp load, VkAttachmentStoreOp store, VkImageLayout initialLayout, VkImageLayout finalLayout)
RenderPassBuilder& RenderPassBuilder::AddAttachment(VkFormat format, VkSampleCountFlagBits samples, VkAttachmentLoadOp load, VkAttachmentStoreOp store, VkImageLayout initialLayout, VkImageLayout finalLayout)
{
VkAttachmentDescription attachment = {};
attachment.format = format;
@ -1005,9 +1099,10 @@ void RenderPassBuilder::addAttachment(VkFormat format, VkSampleCountFlagBits sam
attachments.push_back(attachment);
renderPassInfo.pAttachments = attachments.data();
renderPassInfo.attachmentCount = (uint32_t)attachments.size();
return *this;
}
void RenderPassBuilder::addDepthStencilAttachment(VkFormat format, VkSampleCountFlagBits samples, VkAttachmentLoadOp load, VkAttachmentStoreOp store, VkAttachmentLoadOp stencilLoad, VkAttachmentStoreOp stencilStore, VkImageLayout initialLayout, VkImageLayout finalLayout)
RenderPassBuilder& RenderPassBuilder::AddDepthStencilAttachment(VkFormat format, VkSampleCountFlagBits samples, VkAttachmentLoadOp load, VkAttachmentStoreOp store, VkAttachmentLoadOp stencilLoad, VkAttachmentStoreOp stencilStore, VkImageLayout initialLayout, VkImageLayout finalLayout)
{
VkAttachmentDescription attachment = {};
attachment.format = format;
@ -1021,9 +1116,10 @@ void RenderPassBuilder::addDepthStencilAttachment(VkFormat format, VkSampleCount
attachments.push_back(attachment);
renderPassInfo.pAttachments = attachments.data();
renderPassInfo.attachmentCount = (uint32_t)attachments.size();
return *this;
}
void RenderPassBuilder::addExternalSubpassDependency(VkPipelineStageFlags srcStageMask, VkPipelineStageFlags dstStageMask, VkAccessFlags srcAccessMask, VkAccessFlags dstAccessMask)
RenderPassBuilder& RenderPassBuilder::AddExternalSubpassDependency(VkPipelineStageFlags srcStageMask, VkPipelineStageFlags dstStageMask, VkAccessFlags srcAccessMask, VkAccessFlags dstAccessMask)
{
VkSubpassDependency dependency = {};
dependency.srcSubpass = VK_SUBPASS_EXTERNAL;
@ -1036,9 +1132,10 @@ void RenderPassBuilder::addExternalSubpassDependency(VkPipelineStageFlags srcSta
dependencies.push_back(dependency);
renderPassInfo.pDependencies = dependencies.data();
renderPassInfo.dependencyCount = (uint32_t)dependencies.size();
return *this;
}
void RenderPassBuilder::addSubpass()
RenderPassBuilder& RenderPassBuilder::AddSubpass()
{
VkSubpassDescription subpass = {};
subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
@ -1048,9 +1145,10 @@ void RenderPassBuilder::addSubpass()
renderPassInfo.subpassCount = (uint32_t)subpasses.size();
subpassData.push_back(std::make_unique<SubpassData>());
return *this;
}
void RenderPassBuilder::addSubpassColorAttachmentRef(uint32_t index, VkImageLayout layout)
RenderPassBuilder& RenderPassBuilder::AddSubpassColorAttachmentRef(uint32_t index, VkImageLayout layout)
{
VkAttachmentReference colorAttachmentRef = {};
colorAttachmentRef.attachment = index;
@ -1059,9 +1157,10 @@ void RenderPassBuilder::addSubpassColorAttachmentRef(uint32_t index, VkImageLayo
subpassData.back()->colorRefs.push_back(colorAttachmentRef);
subpasses.back().pColorAttachments = subpassData.back()->colorRefs.data();
subpasses.back().colorAttachmentCount = (uint32_t)subpassData.back()->colorRefs.size();
return *this;
}
void RenderPassBuilder::addSubpassDepthStencilAttachmentRef(uint32_t index, VkImageLayout layout)
RenderPassBuilder& RenderPassBuilder::AddSubpassDepthStencilAttachmentRef(uint32_t index, VkImageLayout layout)
{
VkAttachmentReference& depthAttachmentRef = subpassData.back()->depthRef;
depthAttachmentRef.attachment = index;
@ -1069,33 +1168,38 @@ void RenderPassBuilder::addSubpassDepthStencilAttachmentRef(uint32_t index, VkIm
VkSubpassDescription& subpass = subpasses.back();
subpass.pDepthStencilAttachment = &depthAttachmentRef;
return *this;
}
std::unique_ptr<VulkanRenderPass> RenderPassBuilder::create(VulkanDevice* device)
std::unique_ptr<VulkanRenderPass> RenderPassBuilder::Create(VulkanDevice* device)
{
VkRenderPass renderPass = 0;
VkResult result = vkCreateRenderPass(device->device, &renderPassInfo, nullptr, &renderPass);
CheckVulkanError(result, "Could not create render pass");
return std::make_unique<VulkanRenderPass>(device, renderPass);
auto obj = std::make_unique<VulkanRenderPass>(device, renderPass);
if (debugName)
obj->SetDebugName(debugName);
return obj;
}
/////////////////////////////////////////////////////////////////////////////
void PipelineBarrier::addMemory(VkAccessFlags srcAccessMask, VkAccessFlags dstAccessMask)
PipelineBarrier& PipelineBarrier::AddMemory(VkAccessFlags srcAccessMask, VkAccessFlags dstAccessMask)
{
VkMemoryBarrier barrier = { };
barrier.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER;
barrier.srcAccessMask = srcAccessMask;
barrier.dstAccessMask = dstAccessMask;
memoryBarriers.push_back(barrier);
return *this;
}
void PipelineBarrier::addBuffer(VulkanBuffer* buffer, VkAccessFlags srcAccessMask, VkAccessFlags dstAccessMask)
PipelineBarrier& PipelineBarrier::AddBuffer(VulkanBuffer* buffer, VkAccessFlags srcAccessMask, VkAccessFlags dstAccessMask)
{
addBuffer(buffer, 0, buffer->size, srcAccessMask, dstAccessMask);
return AddBuffer(buffer, 0, buffer->size, srcAccessMask, dstAccessMask);
}
void PipelineBarrier::addBuffer(VulkanBuffer* buffer, VkDeviceSize offset, VkDeviceSize size, VkAccessFlags srcAccessMask, VkAccessFlags dstAccessMask)
PipelineBarrier& PipelineBarrier::AddBuffer(VulkanBuffer* buffer, VkDeviceSize offset, VkDeviceSize size, VkAccessFlags srcAccessMask, VkAccessFlags dstAccessMask)
{
VkBufferMemoryBarrier barrier = { };
barrier.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER;
@ -1107,14 +1211,15 @@ void PipelineBarrier::addBuffer(VulkanBuffer* buffer, VkDeviceSize offset, VkDev
barrier.offset = offset;
barrier.size = size;
bufferMemoryBarriers.push_back(barrier);
return *this;
}
void PipelineBarrier::addImage(VulkanImage* image, VkImageLayout oldLayout, VkImageLayout newLayout, VkAccessFlags srcAccessMask, VkAccessFlags dstAccessMask, VkImageAspectFlags aspectMask, int baseMipLevel, int levelCount)
PipelineBarrier& PipelineBarrier::AddImage(VulkanImage* image, VkImageLayout oldLayout, VkImageLayout newLayout, VkAccessFlags srcAccessMask, VkAccessFlags dstAccessMask, VkImageAspectFlags aspectMask, int baseMipLevel, int levelCount)
{
addImage(image->image, oldLayout, newLayout, srcAccessMask, dstAccessMask, aspectMask, baseMipLevel, levelCount);
return AddImage(image->image, oldLayout, newLayout, srcAccessMask, dstAccessMask, aspectMask, baseMipLevel, levelCount);
}
void PipelineBarrier::addImage(VkImage image, VkImageLayout oldLayout, VkImageLayout newLayout, VkAccessFlags srcAccessMask, VkAccessFlags dstAccessMask, VkImageAspectFlags aspectMask, int baseMipLevel, int levelCount)
PipelineBarrier& PipelineBarrier::AddImage(VkImage image, VkImageLayout oldLayout, VkImageLayout newLayout, VkAccessFlags srcAccessMask, VkAccessFlags dstAccessMask, VkImageAspectFlags aspectMask, int baseMipLevel, int levelCount)
{
VkImageMemoryBarrier barrier = { };
barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
@ -1131,9 +1236,10 @@ void PipelineBarrier::addImage(VkImage image, VkImageLayout oldLayout, VkImageLa
barrier.subresourceRange.baseArrayLayer = 0;
barrier.subresourceRange.layerCount = 1;
imageMemoryBarriers.push_back(barrier);
return *this;
}
void PipelineBarrier::addQueueTransfer(int srcFamily, int dstFamily, VulkanBuffer* buffer, VkAccessFlags srcAccessMask, VkAccessFlags dstAccessMask)
PipelineBarrier& PipelineBarrier::AddQueueTransfer(int srcFamily, int dstFamily, VulkanBuffer* buffer, VkAccessFlags srcAccessMask, VkAccessFlags dstAccessMask)
{
VkBufferMemoryBarrier barrier = { };
barrier.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER;
@ -1145,9 +1251,10 @@ void PipelineBarrier::addQueueTransfer(int srcFamily, int dstFamily, VulkanBuffe
barrier.offset = 0;
barrier.size = buffer->size;
bufferMemoryBarriers.push_back(barrier);
return *this;
}
void PipelineBarrier::addQueueTransfer(int srcFamily, int dstFamily, VulkanImage* image, VkImageLayout layout, VkImageAspectFlags aspectMask, int baseMipLevel, int levelCount)
PipelineBarrier& PipelineBarrier::AddQueueTransfer(int srcFamily, int dstFamily, VulkanImage* image, VkImageLayout layout, VkImageAspectFlags aspectMask, int baseMipLevel, int levelCount)
{
VkImageMemoryBarrier barrier = { };
barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
@ -1162,9 +1269,10 @@ void PipelineBarrier::addQueueTransfer(int srcFamily, int dstFamily, VulkanImage
barrier.subresourceRange.baseArrayLayer = 0;
barrier.subresourceRange.layerCount = 1;
imageMemoryBarriers.push_back(barrier);
return *this;
}
void PipelineBarrier::execute(VulkanCommandBuffer* commandBuffer, VkPipelineStageFlags srcStageMask, VkPipelineStageFlags dstStageMask, VkDependencyFlags dependencyFlags)
void PipelineBarrier::Execute(VulkanCommandBuffer* commandBuffer, VkPipelineStageFlags srcStageMask, VkPipelineStageFlags dstStageMask, VkDependencyFlags dependencyFlags)
{
commandBuffer->pipelineBarrier(
srcStageMask, dstStageMask, dependencyFlags,
@ -1180,14 +1288,15 @@ QueueSubmit::QueueSubmit()
submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
}
void QueueSubmit::addCommandBuffer(VulkanCommandBuffer* buffer)
QueueSubmit& QueueSubmit::AddCommandBuffer(VulkanCommandBuffer* buffer)
{
commandBuffers.push_back(buffer->buffer);
submitInfo.pCommandBuffers = commandBuffers.data();
submitInfo.commandBufferCount = (uint32_t)commandBuffers.size();
return *this;
}
void QueueSubmit::addWait(VkPipelineStageFlags waitStageMask, VulkanSemaphore* semaphore)
QueueSubmit& QueueSubmit::AddWait(VkPipelineStageFlags waitStageMask, VulkanSemaphore* semaphore)
{
waitStages.push_back(waitStageMask);
waitSemaphores.push_back(semaphore->semaphore);
@ -1195,16 +1304,18 @@ void QueueSubmit::addWait(VkPipelineStageFlags waitStageMask, VulkanSemaphore* s
submitInfo.pWaitDstStageMask = waitStages.data();
submitInfo.pWaitSemaphores = waitSemaphores.data();
submitInfo.waitSemaphoreCount = (uint32_t)waitSemaphores.size();
return *this;
}
void QueueSubmit::addSignal(VulkanSemaphore* semaphore)
QueueSubmit& QueueSubmit::AddSignal(VulkanSemaphore* semaphore)
{
signalSemaphores.push_back(semaphore->semaphore);
submitInfo.pSignalSemaphores = signalSemaphores.data();
submitInfo.signalSemaphoreCount = (uint32_t)signalSemaphores.size();
return *this;
}
void QueueSubmit::execute(VulkanDevice* device, VkQueue queue, VulkanFence* fence)
void QueueSubmit::Execute(VulkanDevice* device, VkQueue queue, VulkanFence* fence)
{
VkResult result = vkQueueSubmit(device->graphicsQueue, 1, &submitInfo, fence ? fence->fence : VK_NULL_HANDLE);
CheckVulkanError(result, "Could not submit command buffer");
@ -1212,12 +1323,12 @@ void QueueSubmit::execute(VulkanDevice* device, VkQueue queue, VulkanFence* fenc
/////////////////////////////////////////////////////////////////////////////
void WriteDescriptors::addBuffer(VulkanDescriptorSet* descriptorSet, int binding, VkDescriptorType type, VulkanBuffer* buffer)
WriteDescriptors& WriteDescriptors::AddBuffer(VulkanDescriptorSet* descriptorSet, int binding, VkDescriptorType type, VulkanBuffer* buffer)
{
addBuffer(descriptorSet, binding, type, buffer, 0, buffer->size);
return AddBuffer(descriptorSet, binding, type, buffer, 0, buffer->size);
}
void WriteDescriptors::addBuffer(VulkanDescriptorSet* descriptorSet, int binding, VkDescriptorType type, VulkanBuffer* buffer, size_t offset, size_t range)
WriteDescriptors& WriteDescriptors::AddBuffer(VulkanDescriptorSet* descriptorSet, int binding, VkDescriptorType type, VulkanBuffer* buffer, size_t offset, size_t range)
{
VkDescriptorBufferInfo bufferInfo = {};
bufferInfo.buffer = buffer->buffer;
@ -1237,9 +1348,10 @@ void WriteDescriptors::addBuffer(VulkanDescriptorSet* descriptorSet, int binding
descriptorWrite.pBufferInfo = &extra->bufferInfo;
writes.push_back(descriptorWrite);
writeExtras.push_back(std::move(extra));
return *this;
}
void WriteDescriptors::addStorageImage(VulkanDescriptorSet* descriptorSet, int binding, VulkanImageView* view, VkImageLayout imageLayout)
WriteDescriptors& WriteDescriptors::AddStorageImage(VulkanDescriptorSet* descriptorSet, int binding, VulkanImageView* view, VkImageLayout imageLayout)
{
VkDescriptorImageInfo imageInfo = {};
imageInfo.imageView = view->view;
@ -1258,9 +1370,10 @@ void WriteDescriptors::addStorageImage(VulkanDescriptorSet* descriptorSet, int b
descriptorWrite.pImageInfo = &extra->imageInfo;
writes.push_back(descriptorWrite);
writeExtras.push_back(std::move(extra));
return *this;
}
void WriteDescriptors::addCombinedImageSampler(VulkanDescriptorSet* descriptorSet, int binding, VulkanImageView* view, VulkanSampler* sampler, VkImageLayout imageLayout)
WriteDescriptors& WriteDescriptors::AddCombinedImageSampler(VulkanDescriptorSet* descriptorSet, int binding, VulkanImageView* view, VulkanSampler* sampler, VkImageLayout imageLayout)
{
VkDescriptorImageInfo imageInfo = {};
imageInfo.imageView = view->view;
@ -1280,9 +1393,10 @@ void WriteDescriptors::addCombinedImageSampler(VulkanDescriptorSet* descriptorSe
descriptorWrite.pImageInfo = &extra->imageInfo;
writes.push_back(descriptorWrite);
writeExtras.push_back(std::move(extra));
return *this;
}
void WriteDescriptors::addAccelerationStructure(VulkanDescriptorSet* descriptorSet, int binding, VulkanAccelerationStructure* accelStruct)
WriteDescriptors& WriteDescriptors::AddAccelerationStructure(VulkanDescriptorSet* descriptorSet, int binding, VulkanAccelerationStructure* accelStruct)
{
auto extra = std::make_unique<WriteExtra>();
extra->accelStruct = {};
@ -1300,9 +1414,10 @@ void WriteDescriptors::addAccelerationStructure(VulkanDescriptorSet* descriptorS
descriptorWrite.pNext = &extra->accelStruct;
writes.push_back(descriptorWrite);
writeExtras.push_back(std::move(extra));
return *this;
}
void WriteDescriptors::updateSets(VulkanDevice* device)
void WriteDescriptors::Execute(VulkanDevice* device)
{
vkUpdateDescriptorSets(device->device, (uint32_t)writes.size(), writes.data(), 0, nullptr);
}

View file

@ -9,21 +9,23 @@ class ImageBuilder
public:
ImageBuilder();
void setSize(int width, int height, int miplevels = 1, int arrayLayers = 1);
void setSamples(VkSampleCountFlagBits samples);
void setFormat(VkFormat format);
void setUsage(VkImageUsageFlags imageUsage, VmaMemoryUsage memoryUsage = VMA_MEMORY_USAGE_GPU_ONLY, VmaAllocationCreateFlags allocFlags = 0);
void setMemoryType(VkMemoryPropertyFlags requiredFlags, VkMemoryPropertyFlags preferredFlags, uint32_t memoryTypeBits = 0);
void setLinearTiling();
ImageBuilder& Size(int width, int height, int miplevels = 1, int arrayLayers = 1);
ImageBuilder& Samples(VkSampleCountFlagBits samples);
ImageBuilder& Format(VkFormat format);
ImageBuilder& Usage(VkImageUsageFlags imageUsage, VmaMemoryUsage memoryUsage = VMA_MEMORY_USAGE_GPU_ONLY, VmaAllocationCreateFlags allocFlags = 0);
ImageBuilder& MemoryType(VkMemoryPropertyFlags requiredFlags, VkMemoryPropertyFlags preferredFlags, uint32_t memoryTypeBits = 0);
ImageBuilder& LinearTiling();
ImageBuilder& DebugName(const char* name) { debugName = name; return *this; }
bool isFormatSupported(VulkanDevice *device, VkFormatFeatureFlags bufferFeatures = 0);
bool IsFormatSupported(VulkanDevice *device, VkFormatFeatureFlags bufferFeatures = 0);
std::unique_ptr<VulkanImage> create(VulkanDevice *device, VkDeviceSize* allocatedBytes = nullptr);
std::unique_ptr<VulkanImage> tryCreate(VulkanDevice *device);
std::unique_ptr<VulkanImage> Create(VulkanDevice *device, VkDeviceSize* allocatedBytes = nullptr);
std::unique_ptr<VulkanImage> TryCreate(VulkanDevice *device);
private:
VkImageCreateInfo imageInfo = {};
VmaAllocationCreateInfo allocInfo = {};
const char* debugName = nullptr;
};
class ImageViewBuilder
@ -31,13 +33,15 @@ class ImageViewBuilder
public:
ImageViewBuilder();
void setType(VkImageViewType type);
void setImage(VulkanImage *image, VkFormat format, VkImageAspectFlags aspectMask = VK_IMAGE_ASPECT_COLOR_BIT);
ImageViewBuilder& Type(VkImageViewType type);
ImageViewBuilder& Image(VulkanImage *image, VkFormat format, VkImageAspectFlags aspectMask = VK_IMAGE_ASPECT_COLOR_BIT);
ImageViewBuilder& DebugName(const char* name) { debugName = name; return *this; }
std::unique_ptr<VulkanImageView> create(VulkanDevice *device);
std::unique_ptr<VulkanImageView> Create(VulkanDevice *device);
private:
VkImageViewCreateInfo viewInfo = {};
const char* debugName = nullptr;
};
class SamplerBuilder
@ -45,18 +49,20 @@ class SamplerBuilder
public:
SamplerBuilder();
void setAddressMode(VkSamplerAddressMode addressMode);
void setAddressMode(VkSamplerAddressMode u, VkSamplerAddressMode v, VkSamplerAddressMode w);
void setMinFilter(VkFilter minFilter);
void setMagFilter(VkFilter magFilter);
void setMipmapMode(VkSamplerMipmapMode mode);
void setAnisotropy(float maxAnisotropy);
void setMaxLod(float value);
SamplerBuilder& AddressMode(VkSamplerAddressMode addressMode);
SamplerBuilder& AddressMode(VkSamplerAddressMode u, VkSamplerAddressMode v, VkSamplerAddressMode w);
SamplerBuilder& MinFilter(VkFilter minFilter);
SamplerBuilder& MagFilter(VkFilter magFilter);
SamplerBuilder& MipmapMode(VkSamplerMipmapMode mode);
SamplerBuilder& Anisotropy(float maxAnisotropy);
SamplerBuilder& MaxLod(float value);
SamplerBuilder& DebugName(const char* name) { debugName = name; return *this; }
std::unique_ptr<VulkanSampler> create(VulkanDevice *device);
std::unique_ptr<VulkanSampler> Create(VulkanDevice *device);
private:
VkSamplerCreateInfo samplerInfo = {};
const char* debugName = nullptr;
};
class BufferBuilder
@ -64,15 +70,17 @@ class BufferBuilder
public:
BufferBuilder();
void setSize(size_t size);
void setUsage(VkBufferUsageFlags bufferUsage, VmaMemoryUsage memoryUsage = VMA_MEMORY_USAGE_GPU_ONLY, VmaAllocationCreateFlags allocFlags = 0);
void setMemoryType(VkMemoryPropertyFlags requiredFlags, VkMemoryPropertyFlags preferredFlags, uint32_t memoryTypeBits = 0);
BufferBuilder& Size(size_t size);
BufferBuilder& Usage(VkBufferUsageFlags bufferUsage, VmaMemoryUsage memoryUsage = VMA_MEMORY_USAGE_GPU_ONLY, VmaAllocationCreateFlags allocFlags = 0);
BufferBuilder& MemoryType(VkMemoryPropertyFlags requiredFlags, VkMemoryPropertyFlags preferredFlags, uint32_t memoryTypeBits = 0);
BufferBuilder& DebugName(const char* name) { debugName = name; return *this; }
std::unique_ptr<VulkanBuffer> create(VulkanDevice *device);
std::unique_ptr<VulkanBuffer> Create(VulkanDevice *device);
private:
VkBufferCreateInfo bufferInfo = {};
VmaAllocationCreateInfo allocInfo = {};
const char* debugName = nullptr;
};
class ShaderBuilder
@ -80,14 +88,16 @@ class ShaderBuilder
public:
ShaderBuilder();
void setVertexShader(const FString &code);
void setFragmentShader(const FString &code);
ShaderBuilder& VertexShader(const FString &code);
ShaderBuilder& FragmentShader(const FString &code);
ShaderBuilder& DebugName(const char* name) { debugName = name; return *this; }
std::unique_ptr<VulkanShader> create(const char *shadername, VulkanDevice *device);
std::unique_ptr<VulkanShader> Create(const char *shadername, VulkanDevice *device);
private:
FString code;
int stage;
int stage = 0;
const char* debugName = nullptr;
};
class ComputePipelineBuilder
@ -95,14 +105,16 @@ class ComputePipelineBuilder
public:
ComputePipelineBuilder();
void setLayout(VulkanPipelineLayout *layout);
void setComputeShader(VulkanShader *shader);
ComputePipelineBuilder& Layout(VulkanPipelineLayout *layout);
ComputePipelineBuilder& ComputeShader(VulkanShader *shader);
ComputePipelineBuilder& DebugName(const char* name) { debugName = name; return *this; }
std::unique_ptr<VulkanPipeline> create(VulkanDevice *device);
std::unique_ptr<VulkanPipeline> Create(VulkanDevice *device);
private:
VkComputePipelineCreateInfo pipelineInfo = {};
VkPipelineShaderStageCreateInfo stageInfo = {};
const char* debugName = nullptr;
};
class DescriptorSetLayoutBuilder
@ -110,13 +122,15 @@ class DescriptorSetLayoutBuilder
public:
DescriptorSetLayoutBuilder();
void addBinding(int binding, VkDescriptorType type, int arrayCount, VkShaderStageFlags stageFlags);
DescriptorSetLayoutBuilder& AddBinding(int binding, VkDescriptorType type, int arrayCount, VkShaderStageFlags stageFlags);
DescriptorSetLayoutBuilder& DebugName(const char* name) { debugName = name; return *this; }
std::unique_ptr<VulkanDescriptorSetLayout> create(VulkanDevice *device);
std::unique_ptr<VulkanDescriptorSetLayout> Create(VulkanDevice *device);
private:
VkDescriptorSetLayoutCreateInfo layoutInfo = {};
TArray<VkDescriptorSetLayoutBinding> bindings;
const char* debugName = nullptr;
};
class DescriptorPoolBuilder
@ -124,14 +138,16 @@ class DescriptorPoolBuilder
public:
DescriptorPoolBuilder();
void setMaxSets(int value);
void addPoolSize(VkDescriptorType type, int count);
DescriptorPoolBuilder& MaxSets(int value);
DescriptorPoolBuilder& AddPoolSize(VkDescriptorType type, int count);
DescriptorPoolBuilder& DebugName(const char* name) { debugName = name; return *this; }
std::unique_ptr<VulkanDescriptorPool> create(VulkanDevice *device);
std::unique_ptr<VulkanDescriptorPool> Create(VulkanDevice *device);
private:
std::vector<VkDescriptorPoolSize> poolSizes;
VkDescriptorPoolCreateInfo poolInfo = {};
const char* debugName = nullptr;
};
class QueryPoolBuilder
@ -139,12 +155,14 @@ class QueryPoolBuilder
public:
QueryPoolBuilder();
void setQueryType(VkQueryType type, int count, VkQueryPipelineStatisticFlags pipelineStatistics = 0);
QueryPoolBuilder& QueryType(VkQueryType type, int count, VkQueryPipelineStatisticFlags pipelineStatistics = 0);
QueryPoolBuilder& DebugName(const char* name) { debugName = name; return *this; }
std::unique_ptr<VulkanQueryPool> create(VulkanDevice *device);
std::unique_ptr<VulkanQueryPool> Create(VulkanDevice *device);
private:
VkQueryPoolCreateInfo poolInfo = {};
const char* debugName = nullptr;
};
class FramebufferBuilder
@ -152,16 +170,18 @@ class FramebufferBuilder
public:
FramebufferBuilder();
void setRenderPass(VulkanRenderPass *renderPass);
void addAttachment(VulkanImageView *view);
void addAttachment(VkImageView view);
void setSize(int width, int height, int layers = 1);
FramebufferBuilder& RenderPass(VulkanRenderPass *renderPass);
FramebufferBuilder& AddAttachment(VulkanImageView *view);
FramebufferBuilder& AddAttachment(VkImageView view);
FramebufferBuilder& Size(int width, int height, int layers = 1);
FramebufferBuilder& DebugName(const char* name) { debugName = name; return *this; }
std::unique_ptr<VulkanFramebuffer> create(VulkanDevice *device);
std::unique_ptr<VulkanFramebuffer> Create(VulkanDevice *device);
private:
VkFramebufferCreateInfo framebufferInfo = {};
std::vector<VkImageView> attachments;
const char* debugName = nullptr;
};
union FRenderStyle;
@ -171,37 +191,39 @@ class GraphicsPipelineBuilder
public:
GraphicsPipelineBuilder();
void setSubpass(int subpass);
void setLayout(VulkanPipelineLayout *layout);
void setRenderPass(VulkanRenderPass *renderPass);
void setTopology(VkPrimitiveTopology topology);
void setViewport(float x, float y, float width, float height, float minDepth = 0.0f, float maxDepth = 1.0f);
void setScissor(int x, int y, int width, int height);
void setRasterizationSamples(VkSampleCountFlagBits samples);
GraphicsPipelineBuilder& Subpass(int subpass);
GraphicsPipelineBuilder& Layout(VulkanPipelineLayout *layout);
GraphicsPipelineBuilder& RenderPass(VulkanRenderPass *renderPass);
GraphicsPipelineBuilder& Topology(VkPrimitiveTopology topology);
GraphicsPipelineBuilder& Viewport(float x, float y, float width, float height, float minDepth = 0.0f, float maxDepth = 1.0f);
GraphicsPipelineBuilder& Scissor(int x, int y, int width, int height);
GraphicsPipelineBuilder& RasterizationSamples(VkSampleCountFlagBits samples);
void setCull(VkCullModeFlags cullMode, VkFrontFace frontFace);
void setDepthStencilEnable(bool test, bool write, bool stencil);
void setDepthFunc(VkCompareOp func);
void setDepthClampEnable(bool value);
void setDepthBias(bool enable, float biasConstantFactor, float biasClamp, float biasSlopeFactor);
void setColorWriteMask(VkColorComponentFlags mask);
void setStencil(VkStencilOp failOp, VkStencilOp passOp, VkStencilOp depthFailOp, VkCompareOp compareOp, uint32_t compareMask, uint32_t writeMask, uint32_t reference);
GraphicsPipelineBuilder& Cull(VkCullModeFlags cullMode, VkFrontFace frontFace);
GraphicsPipelineBuilder& DepthStencilEnable(bool test, bool write, bool stencil);
GraphicsPipelineBuilder& DepthFunc(VkCompareOp func);
GraphicsPipelineBuilder& DepthClampEnable(bool value);
GraphicsPipelineBuilder& DepthBias(bool enable, float biasConstantFactor, float biasClamp, float biasSlopeFactor);
GraphicsPipelineBuilder& ColorWriteMask(VkColorComponentFlags mask);
GraphicsPipelineBuilder& Stencil(VkStencilOp failOp, VkStencilOp passOp, VkStencilOp depthFailOp, VkCompareOp compareOp, uint32_t compareMask, uint32_t writeMask, uint32_t reference);
void setAdditiveBlendMode();
void setAlphaBlendMode();
void setBlendMode(const FRenderStyle &style);
void setBlendMode(VkBlendOp op, VkBlendFactor src, VkBlendFactor dst);
void setSubpassColorAttachmentCount(int count);
GraphicsPipelineBuilder& AdditiveBlendMode();
GraphicsPipelineBuilder& AlphaBlendMode();
GraphicsPipelineBuilder& BlendMode(const FRenderStyle &style);
GraphicsPipelineBuilder& BlendMode(VkBlendOp op, VkBlendFactor src, VkBlendFactor dst);
GraphicsPipelineBuilder& SubpassColorAttachmentCount(int count);
void addVertexShader(VulkanShader *shader);
void addFragmentShader(VulkanShader *shader);
GraphicsPipelineBuilder& AddVertexShader(VulkanShader *shader);
GraphicsPipelineBuilder& AddFragmentShader(VulkanShader *shader);
void addVertexBufferBinding(int index, size_t stride);
void addVertexAttribute(int location, int binding, VkFormat format, size_t offset);
GraphicsPipelineBuilder& AddVertexBufferBinding(int index, size_t stride);
GraphicsPipelineBuilder& AddVertexAttribute(int location, int binding, VkFormat format, size_t offset);
void addDynamicState(VkDynamicState state);
GraphicsPipelineBuilder& AddDynamicState(VkDynamicState state);
std::unique_ptr<VulkanPipeline> create(VulkanDevice *device);
GraphicsPipelineBuilder& DebugName(const char* name) { debugName = name; return *this; }
std::unique_ptr<VulkanPipeline> Create(VulkanDevice *device);
private:
VkGraphicsPipelineCreateInfo pipelineInfo = { };
@ -222,6 +244,8 @@ private:
std::vector<VkVertexInputBindingDescription> vertexInputBindings;
std::vector<VkVertexInputAttributeDescription> vertexInputAttributes;
std::vector<VkDynamicState> dynamicStates;
const char* debugName = nullptr;
};
class PipelineLayoutBuilder
@ -229,15 +253,18 @@ class PipelineLayoutBuilder
public:
PipelineLayoutBuilder();
void addSetLayout(VulkanDescriptorSetLayout *setLayout);
void addPushConstantRange(VkShaderStageFlags stageFlags, size_t offset, size_t size);
PipelineLayoutBuilder& AddSetLayout(VulkanDescriptorSetLayout *setLayout);
PipelineLayoutBuilder& AddPushConstantRange(VkShaderStageFlags stageFlags, size_t offset, size_t size);
std::unique_ptr<VulkanPipelineLayout> create(VulkanDevice *device);
PipelineLayoutBuilder& DebugName(const char* name) { debugName = name; return *this; }
std::unique_ptr<VulkanPipelineLayout> Create(VulkanDevice *device);
private:
VkPipelineLayoutCreateInfo pipelineLayoutInfo = {};
std::vector<VkDescriptorSetLayout> setLayouts;
std::vector<VkPushConstantRange> pushConstantRanges;
const char* debugName = nullptr;
};
class RenderPassBuilder
@ -245,16 +272,18 @@ class RenderPassBuilder
public:
RenderPassBuilder();
void addAttachment(VkFormat format, VkSampleCountFlagBits samples, VkAttachmentLoadOp load, VkAttachmentStoreOp store, VkImageLayout initialLayout, VkImageLayout finalLayout);
void addDepthStencilAttachment(VkFormat format, VkSampleCountFlagBits samples, VkAttachmentLoadOp load, VkAttachmentStoreOp store, VkAttachmentLoadOp stencilLoad, VkAttachmentStoreOp stencilStore, VkImageLayout initialLayout, VkImageLayout finalLayout);
RenderPassBuilder& AddAttachment(VkFormat format, VkSampleCountFlagBits samples, VkAttachmentLoadOp load, VkAttachmentStoreOp store, VkImageLayout initialLayout, VkImageLayout finalLayout);
RenderPassBuilder& AddDepthStencilAttachment(VkFormat format, VkSampleCountFlagBits samples, VkAttachmentLoadOp load, VkAttachmentStoreOp store, VkAttachmentLoadOp stencilLoad, VkAttachmentStoreOp stencilStore, VkImageLayout initialLayout, VkImageLayout finalLayout);
void addExternalSubpassDependency(VkPipelineStageFlags srcStageMask, VkPipelineStageFlags dstStageMask, VkAccessFlags srcAccessMask, VkAccessFlags dstAccessMask);
RenderPassBuilder& AddExternalSubpassDependency(VkPipelineStageFlags srcStageMask, VkPipelineStageFlags dstStageMask, VkAccessFlags srcAccessMask, VkAccessFlags dstAccessMask);
void addSubpass();
void addSubpassColorAttachmentRef(uint32_t index, VkImageLayout layout);
void addSubpassDepthStencilAttachmentRef(uint32_t index, VkImageLayout layout);
RenderPassBuilder& AddSubpass();
RenderPassBuilder& AddSubpassColorAttachmentRef(uint32_t index, VkImageLayout layout);
RenderPassBuilder& AddSubpassDepthStencilAttachmentRef(uint32_t index, VkImageLayout layout);
std::unique_ptr<VulkanRenderPass> create(VulkanDevice *device);
RenderPassBuilder& DebugName(const char* name) { debugName = name; return *this; }
std::unique_ptr<VulkanRenderPass> Create(VulkanDevice *device);
private:
VkRenderPassCreateInfo renderPassInfo = { };
@ -270,20 +299,22 @@ private:
};
std::vector<std::unique_ptr<SubpassData>> subpassData;
const char* debugName = nullptr;
};
class PipelineBarrier
{
public:
void addMemory(VkAccessFlags srcAccessMask, VkAccessFlags dstAccessMask);
void addBuffer(VulkanBuffer *buffer, VkAccessFlags srcAccessMask, VkAccessFlags dstAccessMask);
void addBuffer(VulkanBuffer *buffer, VkDeviceSize offset, VkDeviceSize size, VkAccessFlags srcAccessMask, VkAccessFlags dstAccessMask);
void addImage(VulkanImage *image, VkImageLayout oldLayout, VkImageLayout newLayout, VkAccessFlags srcAccessMask, VkAccessFlags dstAccessMask, VkImageAspectFlags aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, int baseMipLevel = 0, int levelCount = 1);
void addImage(VkImage image, VkImageLayout oldLayout, VkImageLayout newLayout, VkAccessFlags srcAccessMask, VkAccessFlags dstAccessMask, VkImageAspectFlags aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, int baseMipLevel = 0, int levelCount = 1);
void addQueueTransfer(int srcFamily, int dstFamily, VulkanBuffer *buffer, VkAccessFlags srcAccessMask, VkAccessFlags dstAccessMask);
void addQueueTransfer(int srcFamily, int dstFamily, VulkanImage *image, VkImageLayout layout, VkImageAspectFlags aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, int baseMipLevel = 0, int levelCount = 1);
PipelineBarrier& AddMemory(VkAccessFlags srcAccessMask, VkAccessFlags dstAccessMask);
PipelineBarrier& AddBuffer(VulkanBuffer *buffer, VkAccessFlags srcAccessMask, VkAccessFlags dstAccessMask);
PipelineBarrier& AddBuffer(VulkanBuffer *buffer, VkDeviceSize offset, VkDeviceSize size, VkAccessFlags srcAccessMask, VkAccessFlags dstAccessMask);
PipelineBarrier& AddImage(VulkanImage *image, VkImageLayout oldLayout, VkImageLayout newLayout, VkAccessFlags srcAccessMask, VkAccessFlags dstAccessMask, VkImageAspectFlags aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, int baseMipLevel = 0, int levelCount = 1);
PipelineBarrier& AddImage(VkImage image, VkImageLayout oldLayout, VkImageLayout newLayout, VkAccessFlags srcAccessMask, VkAccessFlags dstAccessMask, VkImageAspectFlags aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, int baseMipLevel = 0, int levelCount = 1);
PipelineBarrier& AddQueueTransfer(int srcFamily, int dstFamily, VulkanBuffer *buffer, VkAccessFlags srcAccessMask, VkAccessFlags dstAccessMask);
PipelineBarrier& AddQueueTransfer(int srcFamily, int dstFamily, VulkanImage *image, VkImageLayout layout, VkImageAspectFlags aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, int baseMipLevel = 0, int levelCount = 1);
void execute(VulkanCommandBuffer *commandBuffer, VkPipelineStageFlags srcStageMask, VkPipelineStageFlags dstStageMask, VkDependencyFlags dependencyFlags = 0);
void Execute(VulkanCommandBuffer *commandBuffer, VkPipelineStageFlags srcStageMask, VkPipelineStageFlags dstStageMask, VkDependencyFlags dependencyFlags = 0);
private:
std::vector<VkMemoryBarrier> memoryBarriers;
@ -296,10 +327,10 @@ class QueueSubmit
public:
QueueSubmit();
void addCommandBuffer(VulkanCommandBuffer *buffer);
void addWait(VkPipelineStageFlags waitStageMask, VulkanSemaphore *semaphore);
void addSignal(VulkanSemaphore *semaphore);
void execute(VulkanDevice *device, VkQueue queue, VulkanFence *fence = nullptr);
QueueSubmit& AddCommandBuffer(VulkanCommandBuffer *buffer);
QueueSubmit& AddWait(VkPipelineStageFlags waitStageMask, VulkanSemaphore *semaphore);
QueueSubmit& AddSignal(VulkanSemaphore *semaphore);
void Execute(VulkanDevice *device, VkQueue queue, VulkanFence *fence = nullptr);
private:
VkSubmitInfo submitInfo = {};
@ -312,13 +343,12 @@ private:
class WriteDescriptors
{
public:
void addBuffer(VulkanDescriptorSet *descriptorSet, int binding, VkDescriptorType type, VulkanBuffer *buffer);
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);
WriteDescriptors& AddBuffer(VulkanDescriptorSet *descriptorSet, int binding, VkDescriptorType type, VulkanBuffer *buffer);
WriteDescriptors& AddBuffer(VulkanDescriptorSet *descriptorSet, int binding, VkDescriptorType type, VulkanBuffer *buffer, size_t offset, size_t range);
WriteDescriptors& AddStorageImage(VulkanDescriptorSet *descriptorSet, int binding, VulkanImageView *view, VkImageLayout imageLayout);
WriteDescriptors& AddCombinedImageSampler(VulkanDescriptorSet *descriptorSet, int binding, VulkanImageView *view, VulkanSampler *sampler, VkImageLayout imageLayout);
WriteDescriptors& AddAccelerationStructure(VulkanDescriptorSet* descriptorSet, int binding, VulkanAccelerationStructure* accelStruct);
void Execute(VulkanDevice *device);
private:
struct WriteExtra

View file

@ -55,9 +55,9 @@ VkCommandBufferManager::VkCommandBufferManager(VulkanFrameBuffer* fb) : fb(fb)
if (fb->device->graphicsTimeQueries)
{
QueryPoolBuilder querybuilder;
querybuilder.setQueryType(VK_QUERY_TYPE_TIMESTAMP, MaxTimestampQueries);
mTimestampQueryPool = querybuilder.create(fb->device);
mTimestampQueryPool = QueryPoolBuilder()
.QueryType(VK_QUERY_TYPE_TIMESTAMP, MaxTimestampQueries)
.Create(fb->device);
GetDrawCommands()->resetQueryPool(mTimestampQueryPool.get(), 0, MaxTimestampQueries);
}
@ -111,21 +111,21 @@ void VkCommandBufferManager::FlushCommands(VulkanCommandBuffer** commands, size_
QueueSubmit submit;
for (size_t i = 0; i < count; i++)
submit.addCommandBuffer(commands[i]);
submit.AddCommandBuffer(commands[i]);
if (mNextSubmit > 0)
submit.addWait(VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, mSubmitSemaphore[(mNextSubmit - 1) % maxConcurrentSubmitCount].get());
submit.AddWait(VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, mSubmitSemaphore[(mNextSubmit - 1) % maxConcurrentSubmitCount].get());
if (finish && presentImageIndex != 0xffffffff)
{
submit.addWait(VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, mSwapChainImageAvailableSemaphore.get());
submit.addSignal(mRenderFinishedSemaphore.get());
submit.AddWait(VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, mSwapChainImageAvailableSemaphore.get());
submit.AddSignal(mRenderFinishedSemaphore.get());
}
if (!lastsubmit)
submit.addSignal(mSubmitSemaphore[currentIndex].get());
submit.AddSignal(mSubmitSemaphore[currentIndex].get());
submit.execute(fb->device, fb->device->graphicsQueue, mSubmitFence[currentIndex].get());
submit.Execute(fb->device, fb->device->graphicsQueue, mSubmitFence[currentIndex].get());
mNextSubmit++;
}

View file

@ -200,9 +200,9 @@ void VulkanFrameBuffer::RenderTextureView(FCanvasTexture* tex, std::function<voi
mRenderState->EndRenderPass();
VkImageTransition barrier0;
barrier0.addImage(image, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, true);
barrier0.execute(mCommands->GetDrawCommands());
VkImageTransition()
.AddImage(image, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, true)
.Execute(mCommands->GetDrawCommands());
mRenderState->SetRenderTarget(image, depthStencil->View.get(), image->Image->width, image->Image->height, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT);
@ -215,9 +215,9 @@ void VulkanFrameBuffer::RenderTextureView(FCanvasTexture* tex, std::function<voi
mRenderState->EndRenderPass();
VkImageTransition barrier1;
barrier1.addImage(image, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, false);
barrier1.execute(mCommands->GetDrawCommands());
VkImageTransition()
.AddImage(image, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, false)
.Execute(mCommands->GetDrawCommands());
mRenderState->SetRenderTarget(&GetBuffers()->SceneColor, GetBuffers()->SceneDepthStencil.View.get(), GetBuffers()->GetWidth(), GetBuffers()->GetHeight(), VK_FORMAT_R16G16B16A16_SFLOAT, GetBuffers()->GetSceneSamples());
@ -341,19 +341,21 @@ void VulkanFrameBuffer::CopyScreenToBuffer(int w, int h, uint8_t *data)
VkTextureImage image;
// Convert from rgba16f to rgba8 using the GPU:
ImageBuilder imgbuilder;
imgbuilder.setFormat(VK_FORMAT_R8G8B8A8_UNORM);
imgbuilder.setUsage(VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT);
imgbuilder.setSize(w, h);
image.Image = imgbuilder.create(device);
image.Image = ImageBuilder()
.Format(VK_FORMAT_R8G8B8A8_UNORM)
.Usage(VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT)
.Size(w, h)
.DebugName("CopyScreenToBuffer")
.Create(device);
GetPostprocess()->BlitCurrentToImage(&image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
// Staging buffer for download
BufferBuilder bufbuilder;
bufbuilder.setSize(w * h * 4);
bufbuilder.setUsage(VK_BUFFER_USAGE_TRANSFER_DST_BIT, VMA_MEMORY_USAGE_GPU_TO_CPU);
auto staging = bufbuilder.create(device);
staging->SetDebugName("CopyScreenToBuffer");
auto staging = BufferBuilder()
.Size(w * h * 4)
.Usage(VK_BUFFER_USAGE_TRANSFER_DST_BIT, VMA_MEMORY_USAGE_GPU_TO_CPU)
.DebugName("CopyScreenToBuffer")
.Create(device);
// Copy from image to buffer
VkBufferImageCopy region = {};

View file

@ -64,12 +64,10 @@ void VkHardwareBuffer::SetData(size_t size, const void *data, BufferUsageType us
if (mBuffer)
{
fb->GetCommands()->DrawDeleteList->Add(std::move(mBuffer));
mBuffer = {};
}
if (mStaging)
{
fb->GetCommands()->TransferDeleteList->Add(std::move(mStaging));
mStaging = {};
}
if (usage == BufferUsageType::Static || usage == BufferUsageType::Stream)
@ -78,17 +76,17 @@ void VkHardwareBuffer::SetData(size_t size, const void *data, BufferUsageType us
mPersistent = false;
BufferBuilder builder;
builder.setUsage(VK_BUFFER_USAGE_TRANSFER_DST_BIT | mBufferType, VMA_MEMORY_USAGE_GPU_ONLY);
builder.setSize(bufsize);
mBuffer = builder.create(fb->device);
mBuffer->SetDebugName(usage == BufferUsageType::Static ? "VkHardwareBuffer.Static" : "VkHardwareBuffer.Stream");
mBuffer = BufferBuilder()
.Usage(VK_BUFFER_USAGE_TRANSFER_DST_BIT | mBufferType, VMA_MEMORY_USAGE_GPU_ONLY)
.Size(bufsize)
.DebugName(usage == BufferUsageType::Static ? "VkHardwareBuffer.Static" : "VkHardwareBuffer.Stream")
.Create(fb->device);
BufferBuilder builder2;
builder2.setUsage(VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VMA_MEMORY_USAGE_CPU_ONLY);
builder2.setSize(bufsize);
mStaging = builder2.create(fb->device);
mStaging->SetDebugName(usage == BufferUsageType::Static ? "VkHardwareBuffer.Staging.Static" : "VkHardwareBuffer.Staging.Stream");
mStaging = BufferBuilder()
.Usage(VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VMA_MEMORY_USAGE_CPU_ONLY)
.Size(bufsize)
.DebugName(usage == BufferUsageType::Static ? "VkHardwareBuffer.Staging.Static" : "VkHardwareBuffer.Staging.Stream")
.Create(fb->device);
if (data)
{
@ -103,14 +101,14 @@ void VkHardwareBuffer::SetData(size_t size, const void *data, BufferUsageType us
{
mPersistent = true;
BufferBuilder builder;
builder.setUsage(mBufferType, VMA_MEMORY_USAGE_UNKNOWN, VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT | VMA_ALLOCATION_CREATE_MAPPED_BIT);
builder.setMemoryType(
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT | VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
builder.setSize(bufsize);
mBuffer = builder.create(fb->device);
mBuffer->SetDebugName("VkHardwareBuffer.Persistent");
mBuffer = BufferBuilder()
.Usage(mBufferType, VMA_MEMORY_USAGE_UNKNOWN, VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT | VMA_ALLOCATION_CREATE_MAPPED_BIT)
.MemoryType(
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT | VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT)
.Size(bufsize)
.DebugName("VkHardwareBuffer.Persistent")
.Create(fb->device);
map = mBuffer->Map(0, bufsize);
if (data)
@ -120,14 +118,14 @@ void VkHardwareBuffer::SetData(size_t size, const void *data, BufferUsageType us
{
mPersistent = false;
BufferBuilder builder;
builder.setUsage(mBufferType, VMA_MEMORY_USAGE_UNKNOWN, 0);
builder.setMemoryType(
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT | VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
builder.setSize(bufsize);
mBuffer = builder.create(fb->device);
mBuffer->SetDebugName("VkHardwareBuffer.Mappable");
mBuffer = BufferBuilder()
.Usage(mBufferType, VMA_MEMORY_USAGE_UNKNOWN, 0)
.MemoryType(
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT | VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT)
.Size(bufsize)
.DebugName("VkHardwareBuffer.Mappable")
.Create(fb->device);
if (data)
{
@ -171,14 +169,14 @@ void VkHardwareBuffer::Resize(size_t newsize)
map = nullptr;
// Create new buffer
BufferBuilder builder;
builder.setUsage(mBufferType, VMA_MEMORY_USAGE_UNKNOWN, VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT | VMA_ALLOCATION_CREATE_MAPPED_BIT);
builder.setMemoryType(
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT | VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
builder.setSize(newsize);
mBuffer = builder.create(fb->device);
mBuffer->SetDebugName("VkHardwareBuffer.Resized");
mBuffer = BufferBuilder()
.Usage(mBufferType, VMA_MEMORY_USAGE_UNKNOWN, VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT | VMA_ALLOCATION_CREATE_MAPPED_BIT)
.MemoryType(
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT | VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT)
.Size(newsize)
.DebugName("VkHardwareBuffer.Resized")
.Create(fb->device);
buffersize = newsize;
// Transfer data from old to new

View file

@ -81,23 +81,24 @@ VkTextureImage *VkHardwareTexture::GetDepthStencil(FTexture *tex)
int w = tex->GetWidth();
int h = tex->GetHeight();
ImageBuilder builder;
builder.setSize(w, h);
builder.setSamples(VK_SAMPLE_COUNT_1_BIT);
builder.setFormat(format);
builder.setUsage(VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT);
mDepthStencil.Image = builder.create(fb->device);
mDepthStencil.Image->SetDebugName("VkHardwareTexture.DepthStencil");
mDepthStencil.Image = ImageBuilder()
.Size(w, h)
.Samples(VK_SAMPLE_COUNT_1_BIT)
.Format(format)
.Usage(VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT)
.DebugName("VkHardwareTexture.DepthStencil")
.Create(fb->device);
mDepthStencil.AspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
ImageViewBuilder viewbuilder;
viewbuilder.setImage(mDepthStencil.Image.get(), format, VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT);
mDepthStencil.View = viewbuilder.create(fb->device);
mDepthStencil.View->SetDebugName("VkHardwareTexture.DepthStencilView");
mDepthStencil.View = ImageViewBuilder()
.Image(mDepthStencil.Image.get(), format, VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)
.DebugName("VkHardwareTexture.DepthStencilView")
.Create(fb->device);
VkImageTransition barrier;
barrier.addImage(&mDepthStencil, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, true);
barrier.execute(fb->GetCommands()->GetTransferCommands());
VkImageTransition()
.AddImage(&mDepthStencil, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, true)
.Execute(fb->GetCommands()->GetTransferCommands());
}
return &mDepthStencil;
}
@ -116,23 +117,21 @@ void VkHardwareTexture::CreateImage(FTexture *tex, int translation, int flags)
int w = tex->GetWidth();
int h = tex->GetHeight();
ImageBuilder imgbuilder;
imgbuilder.setFormat(format);
imgbuilder.setSize(w, h);
imgbuilder.setUsage(VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT);
mImage.Image = imgbuilder.create(fb->device);
mImage.Image->SetDebugName("VkHardwareTexture.mImage");
mImage.Image = ImageBuilder()
.Format(format)
.Size(w, h)
.Usage(VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT)
.DebugName("VkHardwareTexture.mImage")
.Create(fb->device);
ImageViewBuilder viewbuilder;
viewbuilder.setImage(mImage.Image.get(), format);
mImage.View = viewbuilder.create(fb->device);
mImage.View->SetDebugName("VkHardwareTexture.mImageView");
mImage.View = ImageViewBuilder()
.Image(mImage.Image.get(), format)
.DebugName("VkHardwareTexture.mImageView")
.Create(fb->device);
auto cmdbuffer = fb->GetCommands()->GetTransferCommands();
VkImageTransition imageTransition;
imageTransition.addImage(&mImage, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, true);
imageTransition.execute(cmdbuffer);
VkImageTransition()
.AddImage(&mImage, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, true)
.Execute(fb->GetCommands()->GetTransferCommands());
}
}
@ -143,33 +142,33 @@ void VkHardwareTexture::CreateTexture(int w, int h, int pixelsize, VkFormat form
int totalSize = w * h * pixelsize;
BufferBuilder bufbuilder;
bufbuilder.setSize(totalSize);
bufbuilder.setUsage(VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VMA_MEMORY_USAGE_CPU_ONLY);
std::unique_ptr<VulkanBuffer> stagingBuffer = bufbuilder.create(fb->device);
stagingBuffer->SetDebugName("VkHardwareTexture.mStagingBuffer");
auto stagingBuffer = BufferBuilder()
.Size(totalSize)
.Usage(VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VMA_MEMORY_USAGE_CPU_ONLY)
.DebugName("VkHardwareTexture.mStagingBuffer")
.Create(fb->device);
uint8_t *data = (uint8_t*)stagingBuffer->Map(0, totalSize);
memcpy(data, pixels, totalSize);
stagingBuffer->Unmap();
ImageBuilder imgbuilder;
imgbuilder.setFormat(format);
imgbuilder.setSize(w, h, !mipmap ? 1 : GetMipLevels(w, h));
imgbuilder.setUsage(VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT);
mImage.Image = imgbuilder.create(fb->device);
mImage.Image->SetDebugName("VkHardwareTexture.mImage");
mImage.Image = ImageBuilder()
.Format(format)
.Size(w, h, !mipmap ? 1 : GetMipLevels(w, h))
.Usage(VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT)
.DebugName("VkHardwareTexture.mImage")
.Create(fb->device);
ImageViewBuilder viewbuilder;
viewbuilder.setImage(mImage.Image.get(), format);
mImage.View = viewbuilder.create(fb->device);
mImage.View->SetDebugName("VkHardwareTexture.mImageView");
mImage.View = ImageViewBuilder()
.Image(mImage.Image.get(), format)
.DebugName("VkHardwareTexture.mImageView")
.Create(fb->device);
auto cmdbuffer = fb->GetCommands()->GetTransferCommands();
VkImageTransition imageTransition;
imageTransition.addImage(&mImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, true);
imageTransition.execute(cmdbuffer);
VkImageTransition()
.AddImage(&mImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, true)
.Execute(cmdbuffer);
VkBufferImageCopy region = {};
region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
@ -210,29 +209,28 @@ void VkHardwareTexture::AllocateBuffer(int w, int h, int texelsize)
{
VkFormat format = texelsize == 4 ? VK_FORMAT_B8G8R8A8_UNORM : VK_FORMAT_R8_UNORM;
ImageBuilder imgbuilder;
VkDeviceSize allocatedBytes = 0;
imgbuilder.setFormat(format);
imgbuilder.setSize(w, h);
imgbuilder.setLinearTiling();
imgbuilder.setUsage(VK_IMAGE_USAGE_SAMPLED_BIT, VMA_MEMORY_USAGE_UNKNOWN, VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT | VMA_ALLOCATION_CREATE_MAPPED_BIT);
imgbuilder.setMemoryType(
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT | VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
mImage.Image = imgbuilder.create(fb->device, &allocatedBytes);
mImage.Image->SetDebugName("VkHardwareTexture.mImage");
mImage.Image = ImageBuilder()
.Format(format)
.Size(w, h)
.LinearTiling()
.Usage(VK_IMAGE_USAGE_SAMPLED_BIT, VMA_MEMORY_USAGE_UNKNOWN, VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT | VMA_ALLOCATION_CREATE_MAPPED_BIT)
.MemoryType(
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT | VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT)
.DebugName("VkHardwareTexture.mImage")
.Create(fb->device, &allocatedBytes);
mTexelsize = texelsize;
ImageViewBuilder viewbuilder;
viewbuilder.setImage(mImage.Image.get(), format);
mImage.View = viewbuilder.create(fb->device);
mImage.View->SetDebugName("VkHardwareTexture.mImageView");
mImage.View = ImageViewBuilder()
.Image(mImage.Image.get(), format)
.DebugName("VkHardwareTexture.mImageView")
.Create(fb->device);
auto cmdbuffer = fb->GetCommands()->GetTransferCommands();
VkImageTransition imageTransition;
imageTransition.addImage(&mImage, VK_IMAGE_LAYOUT_GENERAL, true);
imageTransition.execute(cmdbuffer);
VkImageTransition()
.AddImage(&mImage, VK_IMAGE_LAYOUT_GENERAL, true)
.Execute(fb->GetCommands()->GetTransferCommands());
bufferpitch = int(allocatedBytes / h / texelsize);
}
@ -257,18 +255,19 @@ void VkHardwareTexture::CreateWipeTexture(int w, int h, const char *name)
{
VkFormat format = VK_FORMAT_B8G8R8A8_UNORM;
ImageBuilder imgbuilder;
imgbuilder.setFormat(format);
imgbuilder.setSize(w, h);
imgbuilder.setUsage(VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, VMA_MEMORY_USAGE_GPU_ONLY);
mImage.Image = imgbuilder.create(fb->device);
mImage.Image->SetDebugName(name);
mImage.Image = ImageBuilder()
.Format(format)
.Size(w, h)
.Usage(VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, VMA_MEMORY_USAGE_GPU_ONLY)
.DebugName(name)
.Create(fb->device);
mTexelsize = 4;
ImageViewBuilder viewbuilder;
viewbuilder.setImage(mImage.Image.get(), format);
mImage.View = viewbuilder.create(fb->device);
mImage.View->SetDebugName(name);
mImage.View = ImageViewBuilder()
.Image(mImage.Image.get(), format)
.DebugName(name)
.Create(fb->device);
if (fb->GetBuffers()->GetWidth() > 0 && fb->GetBuffers()->GetHeight() > 0)
{
@ -279,9 +278,9 @@ void VkHardwareTexture::CreateWipeTexture(int w, int h, const char *name)
// hwrenderer asked image data from a frame buffer that was never written into. Let's give it that..
// (ideally the hwrenderer wouldn't do this, but the calling code is too complex for me to fix)
VkImageTransition transition0;
transition0.addImage(&mImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, true);
transition0.execute(fb->GetCommands()->GetTransferCommands());
VkImageTransition()
.AddImage(&mImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, true)
.Execute(fb->GetCommands()->GetTransferCommands());
VkImageSubresourceRange range = {};
range.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
@ -295,9 +294,9 @@ void VkHardwareTexture::CreateWipeTexture(int w, int h, const char *name)
value.float32[3] = 1.0f;
fb->GetCommands()->GetTransferCommands()->clearColorImage(mImage.Image->image, mImage.Layout, &value, 1, &range);
VkImageTransition transition1;
transition1.addImage(&mImage, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, false);
transition1.execute(fb->GetCommands()->GetTransferCommands());
VkImageTransition()
.AddImage(&mImage, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, false)
.Execute(fb->GetCommands()->GetTransferCommands());
}
}
@ -353,7 +352,7 @@ VulkanDescriptorSet* VkMaterial::GetDescriptorSet(const FMaterialState& state)
MaterialLayerInfo *layer;
auto systex = static_cast<VkHardwareTexture*>(GetLayer(0, state.mTranslation, &layer));
auto systeximage = systex->GetImage(layer->layerTexture, state.mTranslation, layer->scaleFlags);
update.addCombinedImageSampler(descriptor.get(), 0, systeximage->View.get(), sampler, systeximage->Layout);
update.AddCombinedImageSampler(descriptor.get(), 0, systeximage->View.get(), sampler, systeximage->Layout);
if (!(layer->scaleFlags & CTF_Indexed))
{
@ -361,7 +360,7 @@ VulkanDescriptorSet* VkMaterial::GetDescriptorSet(const FMaterialState& state)
{
auto syslayer = static_cast<VkHardwareTexture*>(GetLayer(i, 0, &layer));
auto syslayerimage = syslayer->GetImage(layer->layerTexture, 0, layer->scaleFlags);
update.addCombinedImageSampler(descriptor.get(), i, syslayerimage->View.get(), sampler, syslayerimage->Layout);
update.AddCombinedImageSampler(descriptor.get(), i, syslayerimage->View.get(), sampler, syslayerimage->Layout);
}
}
else
@ -370,7 +369,7 @@ VulkanDescriptorSet* VkMaterial::GetDescriptorSet(const FMaterialState& state)
{
auto syslayer = static_cast<VkHardwareTexture*>(GetLayer(i, translation, &layer));
auto syslayerimage = syslayer->GetImage(layer->layerTexture, 0, layer->scaleFlags);
update.addCombinedImageSampler(descriptor.get(), i, syslayerimage->View.get(), sampler, syslayerimage->Layout);
update.AddCombinedImageSampler(descriptor.get(), i, syslayerimage->View.get(), sampler, syslayerimage->Layout);
}
numLayers = 3;
}
@ -378,10 +377,10 @@ VulkanDescriptorSet* VkMaterial::GetDescriptorSet(const FMaterialState& state)
auto dummyImage = fb->GetTextureManager()->GetNullTextureView();
for (int i = numLayers; i < SHADER_MIN_REQUIRED_TEXTURE_LAYERS; i++)
{
update.addCombinedImageSampler(descriptor.get(), i, dummyImage, sampler, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
update.AddCombinedImageSampler(descriptor.get(), i, dummyImage, sampler, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
}
update.updateSets(fb->device);
update.Execute(fb->device);
mDescriptorSets.emplace_back(clampmode, translationp, std::move(descriptor));
return mDescriptorSets.back().descriptor.get();
}

View file

@ -22,10 +22,10 @@
#include "vk_imagetransition.h"
void VkImageTransition::addImage(VkTextureImage *image, VkImageLayout targetLayout, bool undefinedSrcLayout, int baseMipLevel, int levelCount)
VkImageTransition& VkImageTransition::AddImage(VkTextureImage *image, VkImageLayout targetLayout, bool undefinedSrcLayout, int baseMipLevel, int levelCount)
{
if (image->Layout == targetLayout)
return;
return *this;
VkAccessFlags srcAccess = 0;
VkAccessFlags dstAccess = 0;
@ -91,15 +91,16 @@ void VkImageTransition::addImage(VkTextureImage *image, VkImageLayout targetLayo
I_FatalError("Unimplemented dst image layout transition\n");
}
barrier.addImage(image->Image.get(), undefinedSrcLayout ? VK_IMAGE_LAYOUT_UNDEFINED : image->Layout, targetLayout, srcAccess, dstAccess, aspectMask, baseMipLevel, levelCount);
barrier.AddImage(image->Image.get(), undefinedSrcLayout ? VK_IMAGE_LAYOUT_UNDEFINED : image->Layout, targetLayout, srcAccess, dstAccess, aspectMask, baseMipLevel, levelCount);
needbarrier = true;
image->Layout = targetLayout;
return *this;
}
void VkImageTransition::execute(VulkanCommandBuffer *cmdbuffer)
void VkImageTransition::Execute(VulkanCommandBuffer *cmdbuffer)
{
if (needbarrier)
barrier.execute(cmdbuffer, srcStageMask, dstStageMask);
barrier.Execute(cmdbuffer, srcStageMask, dstStageMask);
}
/////////////////////////////////////////////////////////////////////////////
@ -111,10 +112,10 @@ void VkTextureImage::GenerateMipmaps(VulkanCommandBuffer *cmdbuffer)
int i;
for (i = 1; mipWidth > 1 || mipHeight > 1; i++)
{
PipelineBarrier barrier0;
barrier0.addImage(Image.get(), Layout, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT, VK_IMAGE_ASPECT_COLOR_BIT, i - 1);
barrier0.addImage(Image.get(), VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT, VK_IMAGE_ASPECT_COLOR_BIT, i);
barrier0.execute(cmdbuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
PipelineBarrier()
.AddImage(Image.get(), Layout, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT, VK_IMAGE_ASPECT_COLOR_BIT, i - 1)
.AddImage(Image.get(), VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT, VK_IMAGE_ASPECT_COLOR_BIT, i)
.Execute(cmdbuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
Layout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
int nextWidth = max(mipWidth >> 1, 1);
@ -135,17 +136,17 @@ void VkTextureImage::GenerateMipmaps(VulkanCommandBuffer *cmdbuffer)
blit.dstSubresource.layerCount = 1;
cmdbuffer->blitImage(Image->image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, Image->image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &blit, VK_FILTER_LINEAR);
PipelineBarrier barrier1;
barrier1.addImage(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, i - 1);
barrier1.execute(cmdbuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
PipelineBarrier()
.AddImage(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, i - 1)
.Execute(cmdbuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
mipWidth = nextWidth;
mipHeight = nextHeight;
}
PipelineBarrier barrier2;
barrier2.addImage(Image.get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_ACCESS_TRANSFER_READ_BIT, VK_ACCESS_SHADER_READ_BIT, VK_IMAGE_ASPECT_COLOR_BIT, i - 1);
barrier2.execute(cmdbuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
PipelineBarrier()
.AddImage(Image.get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_ACCESS_TRANSFER_READ_BIT, VK_ACCESS_SHADER_READ_BIT, VK_IMAGE_ASPECT_COLOR_BIT, i - 1)
.Execute(cmdbuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
Layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
}

View file

@ -38,8 +38,8 @@ public:
class VkImageTransition
{
public:
void addImage(VkTextureImage *image, VkImageLayout targetLayout, bool undefinedSrcLayout, int baseMipLevel = 0, int levelCount = 1);
void execute(VulkanCommandBuffer *cmdbuffer);
VkImageTransition& AddImage(VkTextureImage *image, VkImageLayout targetLayout, bool undefinedSrcLayout, int baseMipLevel = 0, int levelCount = 1);
void Execute(VulkanCommandBuffer *cmdbuffer);
private:
PipelineBarrier barrier;

View file

@ -40,35 +40,36 @@ VkPPTexture::VkPPTexture(VulkanFrameBuffer* fb, PPTexture *texture) : fb(fb)
}
ImageBuilder imgbuilder;
imgbuilder.setFormat(format);
imgbuilder.setSize(texture->Width, texture->Height);
imgbuilder.Format(format);
imgbuilder.Size(texture->Width, texture->Height);
if (texture->Data)
imgbuilder.setUsage(VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT);
imgbuilder.Usage(VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT);
else
imgbuilder.setUsage(VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT);
if (!imgbuilder.isFormatSupported(fb->device))
imgbuilder.Usage(VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT);
imgbuilder.DebugName("VkPPTexture");
if (!imgbuilder.IsFormatSupported(fb->device))
I_FatalError("Vulkan device does not support the image format required by a postprocess texture\n");
TexImage.Image = imgbuilder.create(fb->device);
TexImage.Image->SetDebugName("VkPPTexture");
TexImage.Image = imgbuilder.Create(fb->device);
Format = format;
ImageViewBuilder viewbuilder;
viewbuilder.setImage(TexImage.Image.get(), format);
TexImage.View = viewbuilder.create(fb->device);
TexImage.View->SetDebugName("VkPPTextureView");
TexImage.View = ImageViewBuilder()
.Image(TexImage.Image.get(), format)
.DebugName("VkPPTextureView")
.Create(fb->device);
if (texture->Data)
{
size_t totalsize = texture->Width * texture->Height * pixelsize;
BufferBuilder stagingbuilder;
stagingbuilder.setSize(totalsize);
stagingbuilder.setUsage(VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VMA_MEMORY_USAGE_CPU_ONLY);
Staging = stagingbuilder.create(fb->device);
Staging->SetDebugName("VkPPTextureStaging");
VkImageTransition barrier0;
barrier0.addImage(&TexImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, true);
barrier0.execute(fb->GetCommands()->GetTransferCommands());
Staging = BufferBuilder()
.Size(totalsize)
.Usage(VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VMA_MEMORY_USAGE_CPU_ONLY)
.DebugName("VkPPTextureStaging")
.Create(fb->device);
VkImageTransition()
.AddImage(&TexImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, true)
.Execute(fb->GetCommands()->GetTransferCommands());
void *data = Staging->Map(0, totalsize);
memcpy(data, texture->Data.get(), totalsize);
@ -82,15 +83,15 @@ VkPPTexture::VkPPTexture(VulkanFrameBuffer* fb, PPTexture *texture) : fb(fb)
region.imageExtent.height = texture->Height;
fb->GetCommands()->GetTransferCommands()->copyBufferToImage(Staging->buffer, TexImage.Image->image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &region);
VkImageTransition barrier1;
barrier1.addImage(&TexImage, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, false);
barrier1.execute(fb->GetCommands()->GetTransferCommands());
VkImageTransition()
.AddImage(&TexImage, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, false)
.Execute(fb->GetCommands()->GetTransferCommands());
}
else
{
VkImageTransition barrier;
barrier.addImage(&TexImage, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, true);
barrier.execute(fb->GetCommands()->GetTransferCommands());
VkImageTransition()
.AddImage(&TexImage, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, true)
.Execute(fb->GetCommands()->GetTransferCommands());
}
fb->GetTextureManager()->AddPPTexture(this);

View file

@ -93,21 +93,21 @@ void VkRenderBuffers::CreatePipeline(int width, int height)
VkImageTransition barrier;
for (int i = 0; i < NumPipelineImages; i++)
{
ImageBuilder builder;
builder.setSize(width, height);
builder.setFormat(VK_FORMAT_R16G16B16A16_SFLOAT);
builder.setUsage(VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT);
PipelineImage[i].Image = builder.create(fb->device);
PipelineImage[i].Image->SetDebugName("VkRenderBuffers.PipelineImage");
PipelineImage[i].Image = ImageBuilder()
.Size(width, height)
.Format(VK_FORMAT_R16G16B16A16_SFLOAT)
.Usage(VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT)
.DebugName("VkRenderBuffers.PipelineImage")
.Create(fb->device);
ImageViewBuilder viewbuilder;
viewbuilder.setImage(PipelineImage[i].Image.get(), VK_FORMAT_R16G16B16A16_SFLOAT);
PipelineImage[i].View = viewbuilder.create(fb->device);
PipelineImage[i].View->SetDebugName("VkRenderBuffers.PipelineView");
PipelineImage[i].View = ImageViewBuilder()
.Image(PipelineImage[i].Image.get(), VK_FORMAT_R16G16B16A16_SFLOAT)
.DebugName("VkRenderBuffers.PipelineView")
.Create(fb->device);
barrier.addImage(&PipelineImage[i], VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, true);
barrier.AddImage(&PipelineImage[i], VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, true);
}
barrier.execute(fb->GetCommands()->GetDrawCommands());
barrier.Execute(fb->GetCommands()->GetDrawCommands());
}
void VkRenderBuffers::CreateScene(int width, int height, VkSampleCountFlagBits samples)
@ -122,95 +122,98 @@ void VkRenderBuffers::CreateScene(int width, int height, VkSampleCountFlagBits s
CreateSceneNormal(width, height, samples);
CreateSceneFog(width, height, samples);
VkImageTransition barrier;
barrier.addImage(&SceneColor, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, true);
barrier.addImage(&SceneDepthStencil, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, true);
barrier.addImage(&SceneNormal, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, true);
barrier.addImage(&SceneFog, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, true);
barrier.execute(fb->GetCommands()->GetDrawCommands());
VkImageTransition()
.AddImage(&SceneColor, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, true)
.AddImage(&SceneDepthStencil, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, true)
.AddImage(&SceneNormal, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, true)
.AddImage(&SceneFog, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, true)
.Execute(fb->GetCommands()->GetDrawCommands());
}
void VkRenderBuffers::CreateSceneColor(int width, int height, VkSampleCountFlagBits samples)
{
ImageBuilder builder;
builder.setSize(width, height);
builder.setSamples(samples);
builder.setFormat(VK_FORMAT_R16G16B16A16_SFLOAT);
builder.setUsage(VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT);
SceneColor.Image = builder.create(fb->device);
SceneColor.Image->SetDebugName("VkRenderBuffers.SceneColor");
SceneColor.Image = ImageBuilder()
.Size(width, height)
.Samples(samples)
.Format(VK_FORMAT_R16G16B16A16_SFLOAT)
.Usage(VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT)
.DebugName("VkRenderBuffers.SceneColor")
.Create(fb->device);
ImageViewBuilder viewbuilder;
viewbuilder.setImage(SceneColor.Image.get(), VK_FORMAT_R16G16B16A16_SFLOAT);
SceneColor.View = viewbuilder.create(fb->device);
SceneColor.View->SetDebugName("VkRenderBuffers.SceneColorView");
SceneColor.View = ImageViewBuilder()
.Image(SceneColor.Image.get(), VK_FORMAT_R16G16B16A16_SFLOAT)
.DebugName("VkRenderBuffers.SceneColorView")
.Create(fb->device);
}
void VkRenderBuffers::CreateSceneDepthStencil(int width, int height, VkSampleCountFlagBits samples)
{
ImageBuilder builder;
builder.setSize(width, height);
builder.setSamples(samples);
builder.setFormat(SceneDepthStencilFormat);
builder.setUsage(VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT);
if (!builder.isFormatSupported(fb->device))
builder.Size(width, height);
builder.Samples(samples);
builder.Format(SceneDepthStencilFormat);
builder.Usage(VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT);
if (!builder.IsFormatSupported(fb->device))
{
SceneDepthStencilFormat = VK_FORMAT_D32_SFLOAT_S8_UINT;
builder.setFormat(SceneDepthStencilFormat);
if (!builder.isFormatSupported(fb->device))
builder.Format(SceneDepthStencilFormat);
if (!builder.IsFormatSupported(fb->device))
{
I_FatalError("This device does not support any of the required depth stencil image formats.");
}
}
SceneDepthStencil.Image = builder.create(fb->device);
SceneDepthStencil.Image->SetDebugName("VkRenderBuffers.SceneDepthStencil");
builder.DebugName("VkRenderBuffers.SceneDepthStencil");
SceneDepthStencil.Image = builder.Create(fb->device);
SceneDepthStencil.AspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
ImageViewBuilder viewbuilder;
viewbuilder.setImage(SceneDepthStencil.Image.get(), SceneDepthStencilFormat, VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT);
SceneDepthStencil.View = viewbuilder.create(fb->device);
SceneDepthStencil.View->SetDebugName("VkRenderBuffers.SceneDepthStencilView");
SceneDepthStencil.View = ImageViewBuilder()
.Image(SceneDepthStencil.Image.get(), SceneDepthStencilFormat, VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)
.DebugName("VkRenderBuffers.SceneDepthStencilView")
.Create(fb->device);
viewbuilder.setImage(SceneDepthStencil.Image.get(), SceneDepthStencilFormat, VK_IMAGE_ASPECT_DEPTH_BIT);
SceneDepthStencil.DepthOnlyView = viewbuilder.create(fb->device);
SceneDepthStencil.DepthOnlyView->SetDebugName("VkRenderBuffers.SceneDepthView");
SceneDepthStencil.DepthOnlyView = ImageViewBuilder()
.Image(SceneDepthStencil.Image.get(), SceneDepthStencilFormat, VK_IMAGE_ASPECT_DEPTH_BIT)
.DebugName("VkRenderBuffers.SceneDepthView")
.Create(fb->device);
}
void VkRenderBuffers::CreateSceneFog(int width, int height, VkSampleCountFlagBits samples)
{
ImageBuilder builder;
builder.setSize(width, height);
builder.setSamples(samples);
builder.setFormat(VK_FORMAT_R8G8B8A8_UNORM);
builder.setUsage(VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT);
SceneFog.Image = builder.create(fb->device);
SceneFog.Image->SetDebugName("VkRenderBuffers.SceneFog");
SceneFog.Image = ImageBuilder()
.Size(width, height)
.Samples(samples)
.Format(VK_FORMAT_R8G8B8A8_UNORM)
.Usage(VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT)
.DebugName("VkRenderBuffers.SceneFog")
.Create(fb->device);
ImageViewBuilder viewbuilder;
viewbuilder.setImage(SceneFog.Image.get(), VK_FORMAT_R8G8B8A8_UNORM);
SceneFog.View = viewbuilder.create(fb->device);
SceneFog.View->SetDebugName("VkRenderBuffers.SceneFogView");
SceneFog.View = ImageViewBuilder()
.Image(SceneFog.Image.get(), VK_FORMAT_R8G8B8A8_UNORM)
.DebugName("VkRenderBuffers.SceneFogView")
.Create(fb->device);
}
void VkRenderBuffers::CreateSceneNormal(int width, int height, VkSampleCountFlagBits samples)
{
ImageBuilder builder;
builder.setSize(width, height);
builder.setSamples(samples);
builder.setFormat(SceneNormalFormat);
builder.setUsage(VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT);
if (!builder.isFormatSupported(fb->device, VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT))
builder.Size(width, height);
builder.Samples(samples);
builder.Format(SceneNormalFormat);
builder.Usage(VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT);
if (!builder.IsFormatSupported(fb->device, VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT))
{
SceneNormalFormat = VK_FORMAT_R8G8B8A8_UNORM;
builder.setFormat(SceneNormalFormat);
builder.Format(SceneNormalFormat);
}
SceneNormal.Image = builder.create(fb->device);
SceneNormal.Image->SetDebugName("VkRenderBuffers.SceneNormal");
builder.DebugName("VkRenderBuffers.SceneNormal");
ImageViewBuilder viewbuilder;
viewbuilder.setImage(SceneNormal.Image.get(), SceneNormalFormat);
SceneNormal.View = viewbuilder.create(fb->device);
SceneNormal.View->SetDebugName("VkRenderBuffers.SceneNormalView");
SceneNormal.Image = builder.Create(fb->device);
SceneNormal.View = ImageViewBuilder()
.Image(SceneNormal.Image.get(), SceneNormalFormat)
.DebugName("VkRenderBuffers.SceneNormalView")
.Create(fb->device);
}
VulkanFramebuffer* VkRenderBuffers::GetOutput(VkPPRenderPassSetup* passSetup, const PPOutput& output, bool stencilTest, int& framebufferWidth, int& framebufferHeight)
@ -223,10 +226,10 @@ VulkanFramebuffer* VkRenderBuffers::GetOutput(VkPPRenderPassSetup* passSetup, co
if (tex)
{
VkImageTransition imageTransition;
imageTransition.addImage(tex, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, output.Type == PPTextureType::NextPipelineTexture);
imageTransition.AddImage(tex, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, output.Type == PPTextureType::NextPipelineTexture);
if (stencilTest)
imageTransition.addImage(&fb->GetBuffers()->SceneDepthStencil, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, false);
imageTransition.execute(fb->GetCommands()->GetDrawCommands());
imageTransition.AddImage(&fb->GetBuffers()->SceneDepthStencil, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, false);
imageTransition.Execute(fb->GetCommands()->GetDrawCommands());
view = tex->View->view;
w = tex->Image->width;
@ -245,12 +248,13 @@ VulkanFramebuffer* VkRenderBuffers::GetOutput(VkPPRenderPassSetup* passSetup, co
if (!framebuffer)
{
FramebufferBuilder builder;
builder.setRenderPass(passSetup->RenderPass.get());
builder.setSize(w, h);
builder.addAttachment(view);
builder.RenderPass(passSetup->RenderPass.get());
builder.Size(w, h);
builder.AddAttachment(view);
if (stencilTest)
builder.addAttachment(fb->GetBuffers()->SceneDepthStencil.View.get());
framebuffer = builder.create(fb->device);
builder.AddAttachment(fb->GetBuffers()->SceneDepthStencil.View.get());
builder.DebugName("PPOutputFB");
framebuffer = builder.Create(fb->device);
}
framebufferWidth = w;

View file

@ -90,54 +90,53 @@ void VkSamplerManager::CreateHWSamplers()
for (int i = CLAMP_NONE; i <= CLAMP_XY; i++)
{
SamplerBuilder builder;
builder.setMagFilter(TexFilter[filter].magFilter);
builder.setMinFilter(TexFilter[filter].minFilter);
builder.setAddressMode(TexClamp[i].clamp_u, TexClamp[i].clamp_v, VK_SAMPLER_ADDRESS_MODE_REPEAT);
builder.setMipmapMode(TexFilter[filter].mipfilter);
builder.MagFilter(TexFilter[filter].magFilter);
builder.MinFilter(TexFilter[filter].minFilter);
builder.AddressMode(TexClamp[i].clamp_u, TexClamp[i].clamp_v, VK_SAMPLER_ADDRESS_MODE_REPEAT);
builder.MipmapMode(TexFilter[filter].mipfilter);
if (TexFilter[filter].mipmapping)
{
builder.setAnisotropy(gl_texture_filter_anisotropic);
builder.setMaxLod(100.0f); // According to the spec this value is clamped so something high makes it usable for all textures.
builder.Anisotropy(gl_texture_filter_anisotropic);
builder.MaxLod(100.0f); // According to the spec this value is clamped so something high makes it usable for all textures.
}
else
{
builder.setMaxLod(0.25f);
builder.MaxLod(0.25f);
}
mSamplers[i] = builder.create(fb->device);
mSamplers[i]->SetDebugName("VkSamplerManager.mSamplers");
}
{
SamplerBuilder builder;
builder.setMagFilter(TexFilter[filter].magFilter);
builder.setMinFilter(TexFilter[filter].magFilter);
builder.setAddressMode(VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, VK_SAMPLER_ADDRESS_MODE_REPEAT);
builder.setMipmapMode(VK_SAMPLER_MIPMAP_MODE_NEAREST);
builder.setMaxLod(0.25f);
mSamplers[CLAMP_XY_NOMIP] = builder.create(fb->device);
mSamplers[CLAMP_XY_NOMIP]->SetDebugName("VkSamplerManager.mSamplers");
builder.DebugName("VkSamplerManager.mSamplers");
mSamplers[i] = builder.Create(fb->device);
}
mSamplers[CLAMP_XY_NOMIP] = SamplerBuilder()
.MagFilter(TexFilter[filter].magFilter)
.MinFilter(TexFilter[filter].magFilter)
.AddressMode(VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, VK_SAMPLER_ADDRESS_MODE_REPEAT)
.MipmapMode(VK_SAMPLER_MIPMAP_MODE_NEAREST)
.MaxLod(0.25f)
.DebugName("VkSamplerManager.mSamplers")
.Create(fb->device);
for (int i = CLAMP_NOFILTER; i <= CLAMP_NOFILTER_XY; i++)
{
SamplerBuilder builder;
builder.setMagFilter(VK_FILTER_NEAREST);
builder.setMinFilter(VK_FILTER_NEAREST);
builder.setAddressMode(TexClamp[i - CLAMP_NOFILTER].clamp_u, TexClamp[i - CLAMP_NOFILTER].clamp_v, VK_SAMPLER_ADDRESS_MODE_REPEAT);
builder.setMipmapMode(VK_SAMPLER_MIPMAP_MODE_NEAREST);
builder.setMaxLod(0.25f);
mSamplers[i] = builder.create(fb->device);
mSamplers[i]->SetDebugName("VkSamplerManager.mSamplers");
mSamplers[i] = SamplerBuilder()
.MagFilter(VK_FILTER_NEAREST)
.MinFilter(VK_FILTER_NEAREST)
.AddressMode(TexClamp[i - CLAMP_NOFILTER].clamp_u, TexClamp[i - CLAMP_NOFILTER].clamp_v, VK_SAMPLER_ADDRESS_MODE_REPEAT)
.MipmapMode(VK_SAMPLER_MIPMAP_MODE_NEAREST)
.MaxLod(0.25f)
.DebugName("VkSamplerManager.mSamplers")
.Create(fb->device);
}
// CAMTEX is repeating with texture filter and no mipmap
{
SamplerBuilder builder;
builder.setMagFilter(TexFilter[filter].magFilter);
builder.setMinFilter(TexFilter[filter].magFilter);
builder.setAddressMode(VK_SAMPLER_ADDRESS_MODE_REPEAT, VK_SAMPLER_ADDRESS_MODE_REPEAT, VK_SAMPLER_ADDRESS_MODE_REPEAT);
builder.setMipmapMode(VK_SAMPLER_MIPMAP_MODE_NEAREST);
builder.setMaxLod(0.25f);
mSamplers[CLAMP_CAMTEX] = builder.create(fb->device);
mSamplers[CLAMP_CAMTEX]->SetDebugName("VkSamplerManager.mSamplers");
}
mSamplers[CLAMP_CAMTEX] = SamplerBuilder()
.MagFilter(TexFilter[filter].magFilter)
.MinFilter(TexFilter[filter].magFilter)
.AddressMode(VK_SAMPLER_ADDRESS_MODE_REPEAT, VK_SAMPLER_ADDRESS_MODE_REPEAT, VK_SAMPLER_ADDRESS_MODE_REPEAT)
.MipmapMode(VK_SAMPLER_MIPMAP_MODE_NEAREST)
.MaxLod(0.25f)
.DebugName("VkSamplerManager.mSamplers")
.Create(fb->device);
}
void VkSamplerManager::DeleteHWSamplers()
@ -156,34 +155,35 @@ VulkanSampler* VkSamplerManager::Get(PPFilterMode filter, PPWrapMode wrap)
if (sampler)
return sampler.get();
SamplerBuilder builder;
builder.setMipmapMode(VK_SAMPLER_MIPMAP_MODE_NEAREST);
builder.setMinFilter(filter == PPFilterMode::Nearest ? VK_FILTER_NEAREST : VK_FILTER_LINEAR);
builder.setMagFilter(filter == PPFilterMode::Nearest ? VK_FILTER_NEAREST : VK_FILTER_LINEAR);
builder.setAddressMode(wrap == PPWrapMode::Clamp ? VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE : VK_SAMPLER_ADDRESS_MODE_REPEAT);
sampler = builder.create(fb->device);
sampler->SetDebugName("VkPostprocess.mSamplers");
sampler = SamplerBuilder()
.MipmapMode(VK_SAMPLER_MIPMAP_MODE_NEAREST)
.MinFilter(filter == PPFilterMode::Nearest ? VK_FILTER_NEAREST : VK_FILTER_LINEAR)
.MagFilter(filter == PPFilterMode::Nearest ? VK_FILTER_NEAREST : VK_FILTER_LINEAR)
.AddressMode(wrap == PPWrapMode::Clamp ? VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE : VK_SAMPLER_ADDRESS_MODE_REPEAT)
.DebugName("VkPostprocess.mSamplers")
.Create(fb->device);
return sampler.get();
}
void VkSamplerManager::CreateShadowmapSampler()
{
SamplerBuilder samplerBuilder;
samplerBuilder.setMipmapMode(VK_SAMPLER_MIPMAP_MODE_NEAREST);
samplerBuilder.setMinFilter(VK_FILTER_NEAREST);
samplerBuilder.setMagFilter(VK_FILTER_NEAREST);
samplerBuilder.setAddressMode(VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE);
ShadowmapSampler = samplerBuilder.create(fb->device);
ShadowmapSampler->SetDebugName("VkRenderBuffers.ShadowmapSampler");
ShadowmapSampler = SamplerBuilder()
.MipmapMode(VK_SAMPLER_MIPMAP_MODE_NEAREST)
.MinFilter(VK_FILTER_NEAREST)
.MagFilter(VK_FILTER_NEAREST)
.AddressMode(VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE)
.DebugName("VkRenderBuffers.ShadowmapSampler")
.Create(fb->device);
}
void VkSamplerManager::CreateLightmapSampler()
{
SamplerBuilder builder;
builder.setMipmapMode(VK_SAMPLER_MIPMAP_MODE_LINEAR);
builder.setMinFilter(VK_FILTER_LINEAR);
builder.setMagFilter(VK_FILTER_LINEAR);
builder.setAddressMode(VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE);
LightmapSampler = builder.create(fb->device);
LightmapSampler->SetDebugName("VkRenderBuffers.LightmapSampler");
LightmapSampler = SamplerBuilder()
.MipmapMode(VK_SAMPLER_MIPMAP_MODE_LINEAR)
.MinFilter(VK_FILTER_LINEAR)
.MagFilter(VK_FILTER_LINEAR)
.AddressMode(VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE)
.DebugName("VkRenderBuffers.LightmapSampler")
.Create(fb->device);
}

View file

@ -143,40 +143,40 @@ VkPPTexture* VkTextureManager::GetVkTexture(PPTexture* texture)
void VkTextureManager::CreateNullTexture()
{
ImageBuilder imgbuilder;
imgbuilder.setFormat(VK_FORMAT_R8G8B8A8_UNORM);
imgbuilder.setSize(1, 1);
imgbuilder.setUsage(VK_IMAGE_USAGE_SAMPLED_BIT);
NullTexture = imgbuilder.create(fb->device);
NullTexture->SetDebugName("VkDescriptorSetManager.NullTexture");
NullTexture = ImageBuilder()
.Format(VK_FORMAT_R8G8B8A8_UNORM)
.Size(1, 1)
.Usage(VK_IMAGE_USAGE_SAMPLED_BIT)
.DebugName("VkDescriptorSetManager.NullTexture")
.Create(fb->device);
ImageViewBuilder viewbuilder;
viewbuilder.setImage(NullTexture.get(), VK_FORMAT_R8G8B8A8_UNORM);
NullTextureView = viewbuilder.create(fb->device);
NullTextureView->SetDebugName("VkDescriptorSetManager.NullTextureView");
NullTextureView = ImageViewBuilder()
.Image(NullTexture.get(), VK_FORMAT_R8G8B8A8_UNORM)
.DebugName("VkDescriptorSetManager.NullTextureView")
.Create(fb->device);
PipelineBarrier barrier;
barrier.addImage(NullTexture.get(), VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, 0, VK_ACCESS_SHADER_READ_BIT, VK_IMAGE_ASPECT_COLOR_BIT);
barrier.execute(fb->GetCommands()->GetTransferCommands(), VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
PipelineBarrier()
.AddImage(NullTexture.get(), VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, 0, VK_ACCESS_SHADER_READ_BIT, VK_IMAGE_ASPECT_COLOR_BIT)
.Execute(fb->GetCommands()->GetTransferCommands(), VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
}
void VkTextureManager::CreateShadowmap()
{
ImageBuilder builder;
builder.setSize(gl_shadowmap_quality, 1024);
builder.setFormat(VK_FORMAT_R32_SFLOAT);
builder.setUsage(VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT);
Shadowmap.Image = builder.create(fb->device);
Shadowmap.Image->SetDebugName("VkRenderBuffers.Shadowmap");
Shadowmap.Image = ImageBuilder()
.Size(gl_shadowmap_quality, 1024)
.Format(VK_FORMAT_R32_SFLOAT)
.Usage(VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT)
.DebugName("VkRenderBuffers.Shadowmap")
.Create(fb->device);
ImageViewBuilder viewbuilder;
viewbuilder.setImage(Shadowmap.Image.get(), VK_FORMAT_R32_SFLOAT);
Shadowmap.View = viewbuilder.create(fb->device);
Shadowmap.View->SetDebugName("VkRenderBuffers.ShadowmapView");
Shadowmap.View = ImageViewBuilder()
.Image(Shadowmap.Image.get(), VK_FORMAT_R32_SFLOAT)
.DebugName("VkRenderBuffers.ShadowmapView")
.Create(fb->device);
VkImageTransition barrier;
barrier.addImage(&Shadowmap, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, true);
barrier.execute(fb->GetCommands()->GetDrawCommands());
VkImageTransition()
.AddImage(&Shadowmap, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, true)
.Execute(fb->GetCommands()->GetDrawCommands());
}
void VkTextureManager::CreateLightmap()
@ -198,28 +198,28 @@ void VkTextureManager::SetLightmap(int LMTextureSize, int LMTextureCount, const
Lightmap.Reset(fb);
ImageBuilder builder;
builder.setSize(w, h, 1, count);
builder.setFormat(VK_FORMAT_R16G16B16A16_SFLOAT);
builder.setUsage(VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT);
Lightmap.Image = builder.create(fb->device);
Lightmap.Image->SetDebugName("VkRenderBuffers.Lightmap");
Lightmap.Image = ImageBuilder()
.Size(w, h, 1, count)
.Format(VK_FORMAT_R16G16B16A16_SFLOAT)
.Usage(VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT)
.DebugName("VkRenderBuffers.Lightmap")
.Create(fb->device);
ImageViewBuilder viewbuilder;
viewbuilder.setType(VK_IMAGE_VIEW_TYPE_2D_ARRAY);
viewbuilder.setImage(Lightmap.Image.get(), VK_FORMAT_R16G16B16A16_SFLOAT);
Lightmap.View = viewbuilder.create(fb->device);
Lightmap.View->SetDebugName("VkRenderBuffers.LightmapView");
Lightmap.View = ImageViewBuilder()
.Type(VK_IMAGE_VIEW_TYPE_2D_ARRAY)
.Image(Lightmap.Image.get(), VK_FORMAT_R16G16B16A16_SFLOAT)
.DebugName("VkRenderBuffers.LightmapView")
.Create(fb->device);
auto cmdbuffer = fb->GetCommands()->GetTransferCommands();
int totalSize = w * h * count * pixelsize;
BufferBuilder bufbuilder;
bufbuilder.setSize(totalSize);
bufbuilder.setUsage(VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VMA_MEMORY_USAGE_CPU_ONLY);
std::unique_ptr<VulkanBuffer> stagingBuffer = bufbuilder.create(fb->device);
stagingBuffer->SetDebugName("VkHardwareTexture.mStagingBuffer");
auto stagingBuffer = BufferBuilder()
.Size(totalSize)
.Usage(VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VMA_MEMORY_USAGE_CPU_ONLY)
.DebugName("VkHardwareTexture.mStagingBuffer")
.Create(fb->device);
uint16_t one = 0x3c00; // half-float 1.0
const uint16_t* src = LMTextureData.Data();
@ -233,9 +233,9 @@ void VkTextureManager::SetLightmap(int LMTextureSize, int LMTextureCount, const
}
stagingBuffer->Unmap();
VkImageTransition imageTransition;
imageTransition.addImage(&Lightmap, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, true, 0, count);
imageTransition.execute(cmdbuffer);
VkImageTransition()
.AddImage(&Lightmap, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, true, 0, count)
.Execute(cmdbuffer);
VkBufferImageCopy region = {};
region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
@ -245,9 +245,9 @@ void VkTextureManager::SetLightmap(int LMTextureSize, int LMTextureCount, const
region.imageExtent.height = h;
cmdbuffer->copyBufferToImage(stagingBuffer->buffer, Lightmap.Image->image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &region);
VkImageTransition barrier;
barrier.addImage(&Lightmap, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, false, 0, count);
barrier.execute(cmdbuffer);
VkImageTransition()
.AddImage(&Lightmap, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, false, 0, count)
.Execute(cmdbuffer);
fb->GetCommands()->TransferDeleteList->Add(std::move(stagingBuffer));
}