2019-12-05 18:43:54 -05:00
|
|
|
#include "GSH_VulkanClutLoad.h"
|
|
|
|
#include "GSH_VulkanMemoryUtils.h"
|
|
|
|
#include "../GsPixelFormats.h"
|
|
|
|
#include "MemStream.h"
|
|
|
|
#include "nuanceur/Builder.h"
|
|
|
|
#include "nuanceur/generators/SpirvShaderGenerator.h"
|
|
|
|
#include "vulkan/StructDefs.h"
|
|
|
|
|
|
|
|
using namespace GSH_Vulkan;
|
|
|
|
|
|
|
|
#define DESCRIPTOR_LOCATION_MEMORY 0
|
|
|
|
#define DESCRIPTOR_LOCATION_CLUT 1
|
2019-12-11 21:34:37 -05:00
|
|
|
#define DESCRIPTOR_LOCATION_SWIZZLETABLE 2
|
2019-12-05 18:43:54 -05:00
|
|
|
|
2019-12-10 09:39:12 -05:00
|
|
|
CClutLoad::CClutLoad(const ContextPtr& context, const FrameCommandBufferPtr& frameCommandBuffer)
|
2019-12-13 23:21:59 -05:00
|
|
|
: m_context(context)
|
|
|
|
, m_frameCommandBuffer(frameCommandBuffer)
|
|
|
|
, m_pipelines(context->device)
|
2019-12-05 18:43:54 -05:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2020-02-18 13:06:13 -05:00
|
|
|
void CClutLoad::DoClutLoad(uint32 clutBufferOffset, const CGSHandler::TEX0& tex0, const CGSHandler::TEXCLUT& texClut)
|
2019-12-05 18:43:54 -05:00
|
|
|
{
|
|
|
|
auto caps = make_convertible<PIPELINE_CAPS>(0);
|
|
|
|
caps.idx8 = CGsPixelFormats::IsPsmIDTEX8(tex0.nPsm) ? 1 : 0;
|
|
|
|
caps.csm = tex0.nCSM;
|
|
|
|
caps.cpsm = tex0.nCPSM;
|
|
|
|
|
|
|
|
auto loadPipeline = m_pipelines.TryGetPipeline(caps);
|
|
|
|
if(!loadPipeline)
|
|
|
|
{
|
|
|
|
loadPipeline = m_pipelines.RegisterPipeline(caps, CreateLoadPipeline(caps));
|
|
|
|
}
|
|
|
|
|
2020-01-28 13:21:56 -05:00
|
|
|
assert((caps.csm == 0) || (tex0.nCSA == 0));
|
|
|
|
|
2019-12-05 18:43:54 -05:00
|
|
|
LOAD_PARAMS loadParams;
|
|
|
|
loadParams.clutBufPtr = tex0.GetCLUTPtr();
|
2020-01-28 13:21:56 -05:00
|
|
|
loadParams.clutBufWidth = (tex0.nCSM == 0) ? 0x40 : texClut.GetBufWidth();
|
2019-12-05 18:43:54 -05:00
|
|
|
loadParams.csa = tex0.nCSA;
|
2020-01-28 13:21:56 -05:00
|
|
|
loadParams.clutOffsetX = texClut.GetOffsetU();
|
|
|
|
loadParams.clutOffsetY = texClut.GetOffsetV();
|
2019-12-05 18:43:54 -05:00
|
|
|
|
2020-01-16 08:26:39 -05:00
|
|
|
auto descriptorSet = PrepareDescriptorSet(loadPipeline->descriptorSetLayout, tex0.nCPSM);
|
2019-12-10 09:39:12 -05:00
|
|
|
auto commandBuffer = m_frameCommandBuffer->GetCommandBuffer();
|
2019-12-05 18:43:54 -05:00
|
|
|
|
2020-01-21 21:08:08 -05:00
|
|
|
//Add a barrier to ensure writes to GS memory are complete
|
|
|
|
{
|
|
|
|
auto memoryBarrier = Framework::Vulkan::MemoryBarrier();
|
|
|
|
memoryBarrier.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT;
|
|
|
|
memoryBarrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
|
|
|
|
|
|
|
|
m_context->device.vkCmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
|
|
|
|
0, 1, &memoryBarrier, 0, nullptr, 0, nullptr);
|
|
|
|
}
|
|
|
|
|
2020-02-18 13:06:13 -05:00
|
|
|
m_context->device.vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, loadPipeline->pipelineLayout, 0, 1, &descriptorSet, 1, &clutBufferOffset);
|
2019-12-05 18:43:54 -05:00
|
|
|
m_context->device.vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, loadPipeline->pipeline);
|
|
|
|
m_context->device.vkCmdPushConstants(commandBuffer, loadPipeline->pipelineLayout, VK_SHADER_STAGE_COMPUTE_BIT, 0, sizeof(LOAD_PARAMS), &loadParams);
|
|
|
|
m_context->device.vkCmdDispatch(commandBuffer, 1, 1, 1);
|
|
|
|
}
|
|
|
|
|
2020-01-16 08:26:39 -05:00
|
|
|
VkDescriptorSet CClutLoad::PrepareDescriptorSet(VkDescriptorSetLayout descriptorSetLayout, uint32 cpsm)
|
2019-12-05 18:43:54 -05:00
|
|
|
{
|
2020-01-16 08:26:39 -05:00
|
|
|
auto descriptorSetIterator = m_descriptorSetCache.find(cpsm);
|
|
|
|
if(descriptorSetIterator != std::end(m_descriptorSetCache))
|
|
|
|
{
|
|
|
|
return descriptorSetIterator->second;
|
|
|
|
}
|
|
|
|
|
2019-12-05 18:43:54 -05:00
|
|
|
VkResult result = VK_SUCCESS;
|
|
|
|
VkDescriptorSet descriptorSet = VK_NULL_HANDLE;
|
|
|
|
|
|
|
|
//Allocate descriptor set
|
|
|
|
{
|
|
|
|
auto setAllocateInfo = Framework::Vulkan::DescriptorSetAllocateInfo();
|
2019-12-13 23:21:59 -05:00
|
|
|
setAllocateInfo.descriptorPool = m_context->descriptorPool;
|
2019-12-05 18:43:54 -05:00
|
|
|
setAllocateInfo.descriptorSetCount = 1;
|
2019-12-13 23:21:59 -05:00
|
|
|
setAllocateInfo.pSetLayouts = &descriptorSetLayout;
|
2019-12-05 18:43:54 -05:00
|
|
|
|
|
|
|
result = m_context->device.vkAllocateDescriptorSets(m_context->device, &setAllocateInfo, &descriptorSet);
|
|
|
|
CHECKVULKANERROR(result);
|
|
|
|
}
|
|
|
|
|
|
|
|
//Update descriptor set
|
|
|
|
{
|
|
|
|
std::vector<VkWriteDescriptorSet> writes;
|
|
|
|
|
2019-12-17 19:22:27 -05:00
|
|
|
VkDescriptorBufferInfo descriptorMemoryBufferInfo = {};
|
|
|
|
descriptorMemoryBufferInfo.buffer = m_context->memoryBuffer;
|
|
|
|
descriptorMemoryBufferInfo.range = VK_WHOLE_SIZE;
|
2019-12-05 18:43:54 -05:00
|
|
|
|
2020-02-17 13:21:50 -05:00
|
|
|
VkDescriptorBufferInfo descriptorClutBufferInfo = {};
|
|
|
|
descriptorClutBufferInfo.buffer = m_context->clutBuffer;
|
|
|
|
descriptorClutBufferInfo.range = VK_WHOLE_SIZE;
|
2019-12-05 18:43:54 -05:00
|
|
|
|
2019-12-11 21:34:37 -05:00
|
|
|
VkDescriptorImageInfo descriptorSwizzleTableImageInfo = {};
|
2020-01-16 08:26:39 -05:00
|
|
|
descriptorSwizzleTableImageInfo.imageView = m_context->GetSwizzleTable(cpsm);
|
2019-12-11 21:34:37 -05:00
|
|
|
descriptorSwizzleTableImageInfo.imageLayout = VK_IMAGE_LAYOUT_GENERAL;
|
|
|
|
|
2019-12-05 18:43:54 -05:00
|
|
|
//Memory Image Descriptor
|
|
|
|
{
|
|
|
|
auto writeSet = Framework::Vulkan::WriteDescriptorSet();
|
2019-12-13 23:21:59 -05:00
|
|
|
writeSet.dstSet = descriptorSet;
|
|
|
|
writeSet.dstBinding = DESCRIPTOR_LOCATION_MEMORY;
|
2019-12-05 18:43:54 -05:00
|
|
|
writeSet.descriptorCount = 1;
|
2019-12-17 19:22:27 -05:00
|
|
|
writeSet.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
|
|
|
|
writeSet.pBufferInfo = &descriptorMemoryBufferInfo;
|
2019-12-05 18:43:54 -05:00
|
|
|
writes.push_back(writeSet);
|
|
|
|
}
|
|
|
|
|
|
|
|
//CLUT Image Descriptor
|
|
|
|
{
|
|
|
|
auto writeSet = Framework::Vulkan::WriteDescriptorSet();
|
2019-12-13 23:21:59 -05:00
|
|
|
writeSet.dstSet = descriptorSet;
|
|
|
|
writeSet.dstBinding = DESCRIPTOR_LOCATION_CLUT;
|
2019-12-05 18:43:54 -05:00
|
|
|
writeSet.descriptorCount = 1;
|
2020-02-18 13:06:13 -05:00
|
|
|
writeSet.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC;
|
2020-02-17 13:21:50 -05:00
|
|
|
writeSet.pBufferInfo = &descriptorClutBufferInfo;
|
2019-12-05 18:43:54 -05:00
|
|
|
writes.push_back(writeSet);
|
|
|
|
}
|
|
|
|
|
2019-12-11 21:34:37 -05:00
|
|
|
//Swizzle Table Descriptor
|
|
|
|
{
|
|
|
|
auto writeSet = Framework::Vulkan::WriteDescriptorSet();
|
2019-12-13 23:21:59 -05:00
|
|
|
writeSet.dstSet = descriptorSet;
|
|
|
|
writeSet.dstBinding = DESCRIPTOR_LOCATION_SWIZZLETABLE;
|
2019-12-11 21:34:37 -05:00
|
|
|
writeSet.descriptorCount = 1;
|
2019-12-13 23:21:59 -05:00
|
|
|
writeSet.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
|
|
|
|
writeSet.pImageInfo = &descriptorSwizzleTableImageInfo;
|
2019-12-11 21:34:37 -05:00
|
|
|
writes.push_back(writeSet);
|
|
|
|
}
|
|
|
|
|
2020-05-27 08:45:47 -04:00
|
|
|
m_context->device.vkUpdateDescriptorSets(m_context->device, static_cast<uint32_t>(writes.size()), writes.data(), 0, nullptr);
|
2019-12-05 18:43:54 -05:00
|
|
|
}
|
|
|
|
|
2020-01-16 08:26:39 -05:00
|
|
|
m_descriptorSetCache.insert(std::make_pair(cpsm, descriptorSet));
|
|
|
|
|
2019-12-05 18:43:54 -05:00
|
|
|
return descriptorSet;
|
|
|
|
}
|
|
|
|
|
|
|
|
Framework::Vulkan::CShaderModule CClutLoad::CreateLoadShader(const PIPELINE_CAPS& caps)
|
|
|
|
{
|
|
|
|
using namespace Nuanceur;
|
2019-12-13 23:21:59 -05:00
|
|
|
|
2019-12-05 18:43:54 -05:00
|
|
|
auto b = CShaderBuilder();
|
2019-12-13 23:21:59 -05:00
|
|
|
|
2020-01-28 13:21:56 -05:00
|
|
|
assert((caps.csm == 0) || (caps.cpsm == CGSHandler::PSMCT16));
|
2020-01-10 13:26:11 -05:00
|
|
|
|
2020-01-28 13:21:56 -05:00
|
|
|
if(caps.csm == 0)
|
2019-12-05 18:43:54 -05:00
|
|
|
{
|
2020-01-28 13:21:56 -05:00
|
|
|
if(caps.idx8)
|
|
|
|
{
|
|
|
|
b.SetMetadata(CShaderBuilder::METADATA_LOCALSIZE_X, 16);
|
|
|
|
b.SetMetadata(CShaderBuilder::METADATA_LOCALSIZE_Y, 16);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
b.SetMetadata(CShaderBuilder::METADATA_LOCALSIZE_X, 8);
|
|
|
|
b.SetMetadata(CShaderBuilder::METADATA_LOCALSIZE_Y, 2);
|
|
|
|
}
|
2019-12-05 18:43:54 -05:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2020-01-28 13:21:56 -05:00
|
|
|
b.SetMetadata(CShaderBuilder::METADATA_LOCALSIZE_X, (caps.idx8 == 0) ? 16 : 256);
|
|
|
|
b.SetMetadata(CShaderBuilder::METADATA_LOCALSIZE_Y, 1);
|
2019-12-05 18:43:54 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
auto inputInvocationId = CInt4Lvalue(b.CreateInputInt(Nuanceur::SEMANTIC_SYSTEM_GIID));
|
2019-12-17 19:22:27 -05:00
|
|
|
auto memoryBuffer = CArrayUintValue(b.CreateUniformArrayUint("memoryBuffer", DESCRIPTOR_LOCATION_MEMORY));
|
2020-02-17 13:21:50 -05:00
|
|
|
auto clutBuffer = CArrayUintValue(b.CreateUniformArrayUint("clutBuffer", DESCRIPTOR_LOCATION_CLUT));
|
2019-12-11 21:34:37 -05:00
|
|
|
auto swizzleTable = CImageUint2DValue(b.CreateImage2DUint(DESCRIPTOR_LOCATION_SWIZZLETABLE));
|
2019-12-05 18:43:54 -05:00
|
|
|
|
2020-01-28 13:21:56 -05:00
|
|
|
auto loadParams1 = CInt4Lvalue(b.CreateUniformInt4("loadParams1", Nuanceur::UNIFORM_UNIT_PUSHCONSTANT));
|
|
|
|
auto loadParams2 = CInt4Lvalue(b.CreateUniformInt4("loadParams2", Nuanceur::UNIFORM_UNIT_PUSHCONSTANT));
|
2019-12-05 18:43:54 -05:00
|
|
|
|
2020-01-28 13:21:56 -05:00
|
|
|
auto clutBufPtr = loadParams1->x();
|
|
|
|
auto clutBufWidth = loadParams1->y();
|
|
|
|
auto csa = loadParams1->z();
|
2019-12-05 18:43:54 -05:00
|
|
|
|
2020-01-28 13:21:56 -05:00
|
|
|
auto clutOffset = loadParams2->xy();
|
|
|
|
|
|
|
|
auto colorPixel = CUintLvalue(b.CreateTemporaryUint());
|
2020-01-27 12:51:24 -05:00
|
|
|
{
|
2020-01-28 13:21:56 -05:00
|
|
|
auto colorPos = CInt2Lvalue(b.CreateTemporaryInt());
|
|
|
|
if(caps.csm == 0)
|
|
|
|
{
|
|
|
|
colorPos = inputInvocationId->xy();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
colorPos = clutOffset + NewInt2(inputInvocationId->x(), NewInt(b, 0));
|
|
|
|
}
|
|
|
|
|
|
|
|
switch(caps.cpsm)
|
|
|
|
{
|
|
|
|
case CGSHandler::PSMCT32:
|
|
|
|
case CGSHandler::PSMCT24:
|
|
|
|
{
|
|
|
|
auto colorAddress = CMemoryUtils::GetPixelAddress<CGsPixelFormats::STORAGEPSMCT32>(
|
2020-01-31 09:34:48 -05:00
|
|
|
b, swizzleTable, clutBufPtr, clutBufWidth, colorPos);
|
2020-01-28 13:21:56 -05:00
|
|
|
colorPixel = CMemoryUtils::Memory_Read32(b, memoryBuffer, colorAddress);
|
|
|
|
}
|
2019-12-05 18:43:54 -05:00
|
|
|
break;
|
2020-01-28 13:21:56 -05:00
|
|
|
case CGSHandler::PSMCT16:
|
|
|
|
{
|
|
|
|
auto colorAddress = CMemoryUtils::GetPixelAddress<CGsPixelFormats::STORAGEPSMCT16>(
|
2020-01-31 09:34:48 -05:00
|
|
|
b, swizzleTable, clutBufPtr, clutBufWidth, colorPos);
|
2020-01-28 13:21:56 -05:00
|
|
|
colorPixel = CMemoryUtils::Memory_Read16(b, memoryBuffer, colorAddress);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
assert(false);
|
|
|
|
break;
|
|
|
|
}
|
2019-12-05 18:43:54 -05:00
|
|
|
}
|
|
|
|
|
2020-01-28 13:21:56 -05:00
|
|
|
auto clutIndex = CIntLvalue(b.CreateTemporaryInt());
|
|
|
|
if(caps.csm == 0)
|
2019-12-05 18:43:54 -05:00
|
|
|
{
|
2020-01-28 13:21:56 -05:00
|
|
|
if(caps.idx8)
|
|
|
|
{
|
|
|
|
clutIndex = inputInvocationId->x() + (inputInvocationId->y() * NewInt(b, 16));
|
|
|
|
clutIndex = (clutIndex & NewInt(b, ~0x18)) | ((clutIndex & NewInt(b, 0x08)) << NewInt(b, 1)) | ((clutIndex & NewInt(b, 0x10)) >> NewInt(b, 1));
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
clutIndex = inputInvocationId->x() + (inputInvocationId->y() * NewInt(b, 8));
|
|
|
|
clutIndex = clutIndex + (csa * NewInt(b, 16));
|
|
|
|
}
|
2019-12-05 18:43:54 -05:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2020-01-28 13:21:56 -05:00
|
|
|
clutIndex = inputInvocationId->x();
|
2019-12-05 18:43:54 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
switch(caps.cpsm)
|
|
|
|
{
|
|
|
|
case CGSHandler::PSMCT32:
|
2020-01-21 18:10:25 -05:00
|
|
|
case CGSHandler::PSMCT24:
|
2019-12-13 23:21:59 -05:00
|
|
|
{
|
2020-02-17 13:21:50 -05:00
|
|
|
auto colorPixelLo = colorPixel & NewUint(b, 0xFFFF);
|
2019-12-13 23:21:59 -05:00
|
|
|
auto colorPixelHi = (colorPixel >> NewUint(b, 16)) & NewUint(b, 0xFFFF);
|
2020-02-17 13:21:50 -05:00
|
|
|
auto clutIndexLo = clutIndex;
|
|
|
|
auto clutIndexHi = clutIndex + NewInt(b, 0x100);
|
|
|
|
Store(clutBuffer, clutIndexLo, colorPixelLo);
|
|
|
|
Store(clutBuffer, clutIndexHi, colorPixelHi);
|
2019-12-13 23:21:59 -05:00
|
|
|
}
|
|
|
|
break;
|
2020-01-27 12:51:24 -05:00
|
|
|
case CGSHandler::PSMCT16:
|
|
|
|
{
|
2020-02-17 13:21:50 -05:00
|
|
|
Store(clutBuffer, clutIndex, colorPixel);
|
2020-01-27 12:51:24 -05:00
|
|
|
}
|
|
|
|
break;
|
2019-12-05 18:43:54 -05:00
|
|
|
default:
|
|
|
|
assert(false);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Framework::CMemStream shaderStream;
|
|
|
|
Nuanceur::CSpirvShaderGenerator::Generate(shaderStream, b, Nuanceur::CSpirvShaderGenerator::SHADER_TYPE_COMPUTE);
|
|
|
|
shaderStream.Seek(0, Framework::STREAM_SEEK_SET);
|
|
|
|
return Framework::Vulkan::CShaderModule(m_context->device, shaderStream);
|
|
|
|
}
|
|
|
|
|
|
|
|
PIPELINE CClutLoad::CreateLoadPipeline(const PIPELINE_CAPS& caps)
|
|
|
|
{
|
|
|
|
PIPELINE loadPipeline;
|
|
|
|
|
|
|
|
auto loadShader = CreateLoadShader(caps);
|
|
|
|
|
|
|
|
VkResult result = VK_SUCCESS;
|
|
|
|
|
|
|
|
{
|
|
|
|
std::vector<VkDescriptorSetLayoutBinding> bindings;
|
|
|
|
|
|
|
|
//GS memory
|
|
|
|
{
|
|
|
|
VkDescriptorSetLayoutBinding binding = {};
|
2019-12-13 23:21:59 -05:00
|
|
|
binding.binding = DESCRIPTOR_LOCATION_MEMORY;
|
2019-12-17 19:22:27 -05:00
|
|
|
binding.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
|
2019-12-05 18:43:54 -05:00
|
|
|
binding.descriptorCount = 1;
|
2019-12-13 23:21:59 -05:00
|
|
|
binding.stageFlags = VK_SHADER_STAGE_COMPUTE_BIT;
|
2019-12-05 18:43:54 -05:00
|
|
|
bindings.push_back(binding);
|
|
|
|
}
|
|
|
|
|
|
|
|
//CLUT buffer
|
|
|
|
{
|
|
|
|
VkDescriptorSetLayoutBinding binding = {};
|
2019-12-13 23:21:59 -05:00
|
|
|
binding.binding = DESCRIPTOR_LOCATION_CLUT;
|
2020-02-18 13:06:13 -05:00
|
|
|
binding.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC;
|
2019-12-05 18:43:54 -05:00
|
|
|
binding.descriptorCount = 1;
|
2019-12-13 23:21:59 -05:00
|
|
|
binding.stageFlags = VK_SHADER_STAGE_COMPUTE_BIT;
|
2019-12-05 18:43:54 -05:00
|
|
|
bindings.push_back(binding);
|
|
|
|
}
|
|
|
|
|
2019-12-11 21:34:37 -05:00
|
|
|
//Swizzle table
|
|
|
|
{
|
|
|
|
VkDescriptorSetLayoutBinding binding = {};
|
2019-12-13 23:21:59 -05:00
|
|
|
binding.binding = DESCRIPTOR_LOCATION_SWIZZLETABLE;
|
|
|
|
binding.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
|
2019-12-11 21:34:37 -05:00
|
|
|
binding.descriptorCount = 1;
|
2019-12-13 23:21:59 -05:00
|
|
|
binding.stageFlags = VK_SHADER_STAGE_COMPUTE_BIT;
|
2019-12-11 21:34:37 -05:00
|
|
|
bindings.push_back(binding);
|
|
|
|
}
|
|
|
|
|
2019-12-05 18:43:54 -05:00
|
|
|
auto createInfo = Framework::Vulkan::DescriptorSetLayoutCreateInfo();
|
2020-05-27 08:45:47 -04:00
|
|
|
createInfo.bindingCount = static_cast<uint32_t>(bindings.size());
|
2019-12-13 23:21:59 -05:00
|
|
|
createInfo.pBindings = bindings.data();
|
2019-12-05 18:43:54 -05:00
|
|
|
result = m_context->device.vkCreateDescriptorSetLayout(m_context->device, &createInfo, nullptr, &loadPipeline.descriptorSetLayout);
|
|
|
|
CHECKVULKANERROR(result);
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
VkPushConstantRange pushConstantInfo = {};
|
|
|
|
pushConstantInfo.stageFlags = VK_SHADER_STAGE_COMPUTE_BIT;
|
2019-12-13 23:21:59 -05:00
|
|
|
pushConstantInfo.offset = 0;
|
|
|
|
pushConstantInfo.size = sizeof(LOAD_PARAMS);
|
2019-12-05 18:43:54 -05:00
|
|
|
|
|
|
|
auto pipelineLayoutCreateInfo = Framework::Vulkan::PipelineLayoutCreateInfo();
|
|
|
|
pipelineLayoutCreateInfo.pushConstantRangeCount = 1;
|
2019-12-13 23:21:59 -05:00
|
|
|
pipelineLayoutCreateInfo.pPushConstantRanges = &pushConstantInfo;
|
|
|
|
pipelineLayoutCreateInfo.setLayoutCount = 1;
|
|
|
|
pipelineLayoutCreateInfo.pSetLayouts = &loadPipeline.descriptorSetLayout;
|
2019-12-05 18:43:54 -05:00
|
|
|
|
|
|
|
result = m_context->device.vkCreatePipelineLayout(m_context->device, &pipelineLayoutCreateInfo, nullptr, &loadPipeline.pipelineLayout);
|
|
|
|
CHECKVULKANERROR(result);
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
auto createInfo = Framework::Vulkan::ComputePipelineCreateInfo();
|
|
|
|
createInfo.stage.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
|
|
|
|
createInfo.stage.stage = VK_SHADER_STAGE_COMPUTE_BIT;
|
|
|
|
createInfo.stage.pName = "main";
|
|
|
|
createInfo.stage.module = loadShader;
|
|
|
|
createInfo.layout = loadPipeline.pipelineLayout;
|
|
|
|
|
|
|
|
result = m_context->device.vkCreateComputePipelines(m_context->device, VK_NULL_HANDLE, 1, &createInfo, nullptr, &loadPipeline.pipeline);
|
|
|
|
CHECKVULKANERROR(result);
|
|
|
|
}
|
|
|
|
|
|
|
|
return loadPipeline;
|
|
|
|
}
|