Skip to content

Commit

Permalink
Handle overlapping local to local transfers a bit better.
Browse files Browse the repository at this point in the history
  • Loading branch information
jpd002 committed Nov 21, 2023
1 parent 8cae7d1 commit ca72c40
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 9 deletions.
20 changes: 20 additions & 0 deletions Source/gs/GSH_Vulkan/GSH_Vulkan.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1433,6 +1433,26 @@ void CGSH_Vulkan::ProcessLocalToLocalTransfer()
pipelineCaps.srcFormat = bltBuf.nSrcPsm;
pipelineCaps.dstFormat = bltBuf.nDstPsm;

if(bltBuf.GetSrcPtr() == bltBuf.GetDstPtr())
{
//If src and dst pointers are the same, we need to copy the memory area in our memoryBufferCopy.
//This is needed for Tairyou Jigoku for a scrolling effect in the sewer level.
//TODO: Handle overlapping regions (even if memory addresses don't match)

auto [transferAddress, transferSize] = GsTransfer::GetDstRange(bltBuf, trxReg, trxPos);

auto commandBuffer = m_frameCommandBuffer->GetCommandBuffer();

VkBufferCopy bufferCopy = {};
bufferCopy.srcOffset = transferAddress;
bufferCopy.dstOffset = transferAddress;
bufferCopy.size = transferSize;

m_context->device.vkCmdCopyBuffer(commandBuffer, m_context->memoryBuffer, m_context->memoryBufferCopy, 1, &bufferCopy);

pipelineCaps.srcUseMemoryCopy = true;
}

m_transferLocal->SetPipelineCaps(pipelineCaps);
m_transferLocal->DoTransfer();
}
Expand Down
51 changes: 42 additions & 9 deletions Source/gs/GSH_Vulkan/GSH_VulkanTransferLocal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,15 @@

using namespace GSH_Vulkan;

#define DESCRIPTOR_LOCATION_MEMORY 0
#define DESCRIPTOR_LOCATION_SWIZZLETABLE_SRC 1
#define DESCRIPTOR_LOCATION_SWIZZLETABLE_DST 2
#define DESCRIPTOR_LOCATION_MEMORY_8BIT 3
#define DESCRIPTOR_LOCATION_MEMORY_16BIT 4
enum DESCRIPTORS
{
DESCRIPTOR_LOCATION_MEMORY,
DESCRIPTOR_LOCATION_MEMORY_8BIT,
DESCRIPTOR_LOCATION_MEMORY_16BIT,
DESCRIPTOR_LOCATION_MEMORY_COPY,
DESCRIPTOR_LOCATION_SWIZZLETABLE_SRC,
DESCRIPTOR_LOCATION_SWIZZLETABLE_DST,
};

#define TRANSFER_USE_8_16_BIT GSH_VULKAN_IS_DESKTOP

Expand Down Expand Up @@ -100,6 +104,10 @@ VkDescriptorSet CTransferLocal::PrepareDescriptorSet(VkDescriptorSetLayout descr
descriptorMemoryBufferInfo.buffer = m_context->memoryBuffer;
descriptorMemoryBufferInfo.range = VK_WHOLE_SIZE;

VkDescriptorBufferInfo descriptorMemoryCopyBufferInfo = {};
descriptorMemoryCopyBufferInfo.buffer = m_context->memoryBufferCopy;
descriptorMemoryCopyBufferInfo.range = VK_WHOLE_SIZE;

VkDescriptorImageInfo descriptorSrcSwizzleTableInfo = {};
descriptorSrcSwizzleTableInfo.imageView = m_context->GetSwizzleTable(caps.srcPsm);
descriptorSrcSwizzleTableInfo.imageLayout = VK_IMAGE_LAYOUT_GENERAL;
Expand Down Expand Up @@ -143,6 +151,17 @@ VkDescriptorSet CTransferLocal::PrepareDescriptorSet(VkDescriptorSetLayout descr
writes.push_back(writeSet);
}

//Memory Copy Image Descriptor
{
auto writeSet = Framework::Vulkan::WriteDescriptorSet();
writeSet.dstSet = descriptorSet;
writeSet.dstBinding = DESCRIPTOR_LOCATION_MEMORY_COPY;
writeSet.descriptorCount = 1;
writeSet.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
writeSet.pBufferInfo = &descriptorMemoryCopyBufferInfo;
writes.push_back(writeSet);
}

//Src Swizzle Table
{
auto writeSet = Framework::Vulkan::WriteDescriptorSet();
Expand Down Expand Up @@ -189,6 +208,8 @@ Framework::Vulkan::CShaderModule CTransferLocal::CreateShader(const PIPELINE_CAP
auto memoryBuffer8 = CArrayUcharValue(b.CreateUniformArrayUchar("memoryBuffer8", DESCRIPTOR_LOCATION_MEMORY_8BIT));
auto memoryBuffer16 = CArrayUshortValue(b.CreateUniformArrayUshort("memoryBuffer16", DESCRIPTOR_LOCATION_MEMORY_16BIT));
#endif
auto memoryCopyBuffer = CArrayUintValue(b.CreateUniformArrayUint("memoryBuffer", DESCRIPTOR_LOCATION_MEMORY_COPY));

auto srcSwizzleTable = CImageUint2DValue(b.CreateImage2DUint(DESCRIPTOR_LOCATION_SWIZZLETABLE_SRC));
auto dstSwizzleTable = CImageUint2DValue(b.CreateImage2DUint(DESCRIPTOR_LOCATION_SWIZZLETABLE_DST));

Expand All @@ -204,6 +225,8 @@ Framework::Vulkan::CShaderModule CTransferLocal::CreateShader(const PIPELINE_CAP
auto srcOffset = offsetParams->xy();
auto dstOffset = offsetParams->zw();

auto srcBuffer = caps.srcUseMemoryCopy ? memoryCopyBuffer : memoryBuffer;

auto size = sizeParams->xy();

BeginIf(b, inputInvocationId->x() >= size->x());
Expand All @@ -230,28 +253,28 @@ Framework::Vulkan::CShaderModule CTransferLocal::CreateShader(const PIPELINE_CAP
{
auto address = CMemoryUtils::GetPixelAddress<CGsPixelFormats::STORAGEPSMCT32>(
b, srcSwizzleTable, srcBufAddress, srcBufWidth, srcPos);
pixel = CMemoryUtils::Memory_Read32(b, memoryBuffer, address);
pixel = CMemoryUtils::Memory_Read32(b, srcBuffer, address);
}
break;
case CGSHandler::PSMCT16:
{
auto address = CMemoryUtils::GetPixelAddress<CGsPixelFormats::STORAGEPSMCT16>(
b, srcSwizzleTable, srcBufAddress, srcBufWidth, srcPos);
pixel = CMemoryUtils::Memory_Read16(b, memoryBuffer, address);
pixel = CMemoryUtils::Memory_Read16(b, srcBuffer, address);
}
break;
case CGSHandler::PSMT8:
{
auto address = CMemoryUtils::GetPixelAddress<CGsPixelFormats::STORAGEPSMT8>(
b, srcSwizzleTable, srcBufAddress, srcBufWidth, srcPos);
pixel = CMemoryUtils::Memory_Read8(b, memoryBuffer, address);
pixel = CMemoryUtils::Memory_Read8(b, srcBuffer, address);
}
break;
case CGSHandler::PSMT4:
{
auto texAddress = CMemoryUtils::GetPixelAddress_PSMT4(
b, srcSwizzleTable, srcBufAddress, srcBufWidth, srcPos);
pixel = CMemoryUtils::Memory_Read4(b, memoryBuffer, texAddress);
pixel = CMemoryUtils::Memory_Read4(b, srcBuffer, texAddress);
}
break;
default:
Expand Down Expand Up @@ -368,6 +391,16 @@ PIPELINE CTransferLocal::CreatePipeline(const PIPELINE_CAPS& caps)
bindings.push_back(binding);
}

//GS memory copy
{
VkDescriptorSetLayoutBinding binding = {};
binding.binding = DESCRIPTOR_LOCATION_MEMORY_COPY;
binding.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
binding.descriptorCount = 1;
binding.stageFlags = VK_SHADER_STAGE_COMPUTE_BIT;
bindings.push_back(binding);
}

//Src Swizzle Table
{
VkDescriptorSetLayoutBinding binding = {};
Expand Down
1 change: 1 addition & 0 deletions Source/gs/GSH_Vulkan/GSH_VulkanTransferLocal.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ namespace GSH_Vulkan
{
uint32 srcFormat : 6;
uint32 dstFormat : 6;
uint32 srcUseMemoryCopy : 1;
};

struct XFERPARAMS
Expand Down

0 comments on commit ca72c40

Please sign in to comment.