Play-/Source/gs/GSH_Vulkan/GSH_VulkanMemoryUtils.cpp
Jean-Philip Desjardins d7613b9523 Remove fp dst color.
At this state, MGS3 and Castlevania: CoD seem to give proper results. GoW's fog is still a problem.
2021-08-06 16:54:48 -04:00

207 lines
9.5 KiB
C++

#include "GSH_VulkanMemoryUtils.h"
using namespace GSH_Vulkan;
Nuanceur::CIntRvalue CMemoryUtils::GetPixelAddress_PSMT4(Nuanceur::CShaderBuilder& b, Nuanceur::CImageUint2DValue swizzleTable,
Nuanceur::CIntValue bufAddress, Nuanceur::CIntValue bufWidth, Nuanceur::CInt2Value position)
{
auto pageWidth = NewInt(b, CGsPixelFormats::STORAGEPSMT4::PAGEWIDTH);
auto pageHeight = NewInt(b, CGsPixelFormats::STORAGEPSMT4::PAGEHEIGHT);
auto pageSize = NewInt(b, CGsPixelFormats::PAGESIZE);
auto pageNum = (position->x() / pageWidth) + ((position->y() / pageHeight) * bufWidth) / pageWidth;
auto pagePos = NewInt2(position->x() % pageWidth, position->y() % pageHeight);
auto pageOffset = ToInt(Load(swizzleTable, pagePos)->x());
return ((bufAddress + (pageNum * pageSize)) * NewInt(b, 2)) + pageOffset;
}
Nuanceur::CUintRvalue CMemoryUtils::Memory_Read32(Nuanceur::CShaderBuilder& b, Nuanceur::CArrayUintValue memoryBuffer, Nuanceur::CIntValue address)
{
auto wordAddress = address / NewInt(b, 4);
return Load(memoryBuffer, wordAddress);
}
Nuanceur::CUintRvalue CMemoryUtils::Memory_Read24(Nuanceur::CShaderBuilder& b, Nuanceur::CArrayUintValue memoryBuffer, Nuanceur::CIntValue address)
{
auto wordAddress = address / NewInt(b, 4);
return Load(memoryBuffer, wordAddress) & NewUint(b, 0xFFFFFF);
}
Nuanceur::CUintRvalue CMemoryUtils::Memory_Read16(Nuanceur::CShaderBuilder& b, Nuanceur::CArrayUintValue memoryBuffer, Nuanceur::CIntValue address)
{
auto wordAddress = address / NewInt(b, 4);
auto shiftAmount = (ToUint(address) & NewUint(b, 2)) * NewUint(b, 8);
auto pixel = Load(memoryBuffer, wordAddress);
return (pixel >> shiftAmount) & NewUint(b, 0xFFFF);
}
Nuanceur::CUintRvalue CMemoryUtils::Memory_Read8(Nuanceur::CShaderBuilder& b, Nuanceur::CArrayUintValue memoryBuffer, Nuanceur::CIntValue address)
{
auto wordAddress = address / NewInt(b, 4);
auto shiftAmount = (ToUint(address) & NewUint(b, 3)) * NewUint(b, 8);
auto pixel = Load(memoryBuffer, wordAddress);
return (pixel >> shiftAmount) & NewUint(b, 0xFF);
}
Nuanceur::CUintRvalue CMemoryUtils::Memory_Read4(Nuanceur::CShaderBuilder& b, Nuanceur::CArrayUintValue memoryBuffer, Nuanceur::CIntValue nibAddress)
{
auto wordAddress = nibAddress / NewInt(b, 8);
auto shiftAmount = (ToUint(nibAddress) & NewUint(b, 7)) * NewUint(b, 4);
auto pixel = Load(memoryBuffer, wordAddress);
return (pixel >> shiftAmount) & NewUint(b, 0xF);
}
void CMemoryUtils::Memory_Write32(Nuanceur::CShaderBuilder& b, Nuanceur::CArrayUintValue memoryBuffer, Nuanceur::CIntValue address, Nuanceur::CUintValue value)
{
auto wordAddress = address / NewInt(b, 4);
Store(memoryBuffer, wordAddress, value);
}
void CMemoryUtils::Memory_Write24(Nuanceur::CShaderBuilder& b, Nuanceur::CArrayUintValue memoryBuffer, Nuanceur::CIntValue address, Nuanceur::CUintValue value)
{
auto wordAddress = address / NewInt(b, 4);
auto mask = NewUint(b, 0xFF000000);
AtomicAnd(memoryBuffer, wordAddress, mask);
AtomicOr(memoryBuffer, wordAddress, value);
}
void CMemoryUtils::Memory_Write24(Nuanceur::CShaderBuilder& b, Nuanceur::CArrayUcharValue memoryBuffer8, Nuanceur::CArrayUshortValue memoryBuffer16, Nuanceur::CIntValue address, Nuanceur::CUintValue value)
{
Store(memoryBuffer16, address / NewInt(b, 2), ToUshort(value));
Store(memoryBuffer8, address + NewInt(b, 2), ToUchar(value >> NewUint(b, 16)));
}
void CMemoryUtils::Memory_Write16(Nuanceur::CShaderBuilder& b, Nuanceur::CArrayUintValue memoryBuffer, Nuanceur::CIntValue address, Nuanceur::CUintValue value)
{
auto wordAddress = address / NewInt(b, 4);
auto shiftAmount = (ToUint(address) & NewUint(b, 2)) * NewUint(b, 8);
auto mask = NewUint(b, 0xFFFFFFFF) ^ (NewUint(b, 0xFFFF) << shiftAmount);
auto valueWord = value << shiftAmount;
AtomicAnd(memoryBuffer, wordAddress, mask);
AtomicOr(memoryBuffer, wordAddress, valueWord);
}
void CMemoryUtils::Memory_Write16(Nuanceur::CShaderBuilder& b, Nuanceur::CArrayUshortValue memoryBuffer, Nuanceur::CIntValue address, Nuanceur::CUintValue value)
{
Store(memoryBuffer, address / NewInt(b, 2), ToUshort(value));
}
void CMemoryUtils::Memory_Write8(Nuanceur::CShaderBuilder& b, Nuanceur::CArrayUintValue memoryBuffer, Nuanceur::CIntValue address, Nuanceur::CUintValue value)
{
auto wordAddress = address / NewInt(b, 4);
auto shiftAmount = (ToUint(address) & NewUint(b, 3)) * NewUint(b, 8);
auto mask = NewUint(b, 0xFFFFFFFF) ^ (NewUint(b, 0xFF) << shiftAmount);
auto valueWord = value << shiftAmount;
AtomicAnd(memoryBuffer, wordAddress, mask);
AtomicOr(memoryBuffer, wordAddress, valueWord);
}
void CMemoryUtils::Memory_Write8(Nuanceur::CShaderBuilder& b, Nuanceur::CArrayUcharValue memoryBuffer, Nuanceur::CIntValue address, Nuanceur::CUintValue value)
{
Store(memoryBuffer, address, ToUchar(value));
}
void CMemoryUtils::Memory_Write4(Nuanceur::CShaderBuilder& b, Nuanceur::CArrayUintValue memoryBuffer, Nuanceur::CIntValue nibAddress, Nuanceur::CUintValue value)
{
auto wordAddress = nibAddress / NewInt(b, 8);
auto shiftAmount = (ToUint(nibAddress) & NewUint(b, 7)) * NewUint(b, 4);
auto mask = NewUint(b, 0xFFFFFFFF) ^ (NewUint(b, 0xF) << shiftAmount);
auto valueWord = value << shiftAmount;
AtomicAnd(memoryBuffer, wordAddress, mask);
AtomicOr(memoryBuffer, wordAddress, valueWord);
}
Nuanceur::CFloat4Rvalue CMemoryUtils::PSM32ToVec4(Nuanceur::CShaderBuilder& b, Nuanceur::CUintValue inputColor)
{
auto colorR = (inputColor >> NewUint(b, 0)) & NewUint(b, 0xFF);
auto colorG = (inputColor >> NewUint(b, 8)) & NewUint(b, 0xFF);
auto colorB = (inputColor >> NewUint(b, 16)) & NewUint(b, 0xFF);
auto colorA = (inputColor >> NewUint(b, 24)) & NewUint(b, 0xFF);
auto colorFloatR = ToFloat(colorR) / NewFloat(b, 255.f);
auto colorFloatG = ToFloat(colorG) / NewFloat(b, 255.f);
auto colorFloatB = ToFloat(colorB) / NewFloat(b, 255.f);
auto colorFloatA = ToFloat(colorA) / NewFloat(b, 255.f);
return NewFloat4(colorFloatR, colorFloatG, colorFloatB, colorFloatA);
}
Nuanceur::CFloat4Rvalue CMemoryUtils::PSM16ToVec4(Nuanceur::CShaderBuilder& b, Nuanceur::CUintValue inputColor)
{
auto colorR = (inputColor >> NewUint(b, 0)) & NewUint(b, 0x1F);
auto colorG = (inputColor >> NewUint(b, 5)) & NewUint(b, 0x1F);
auto colorB = (inputColor >> NewUint(b, 10)) & NewUint(b, 0x1F);
auto colorA = (inputColor >> NewUint(b, 15)) & NewUint(b, 0x1);
auto colorFloatR = ToFloat(colorR) / NewFloat(b, 31.f);
auto colorFloatG = ToFloat(colorG) / NewFloat(b, 31.f);
auto colorFloatB = ToFloat(colorB) / NewFloat(b, 31.f);
auto colorFloatA = ToFloat(colorA);
return NewFloat4(colorFloatR, colorFloatG, colorFloatB, colorFloatA);
}
Nuanceur::CUintRvalue CMemoryUtils::Vec4ToPSM32(Nuanceur::CShaderBuilder& b, Nuanceur::CFloat4Value inputColor)
{
auto colorR = ToUint(inputColor->x() * NewFloat(b, 255.f)) << NewUint(b, 0);
auto colorG = ToUint(inputColor->y() * NewFloat(b, 255.f)) << NewUint(b, 8);
auto colorB = ToUint(inputColor->z() * NewFloat(b, 255.f)) << NewUint(b, 16);
auto colorA = ToUint(inputColor->w() * NewFloat(b, 255.f)) << NewUint(b, 24);
return colorR | colorG | colorB | colorA;
}
Nuanceur::CUintRvalue CMemoryUtils::Vec4ToPSM16(Nuanceur::CShaderBuilder& b, Nuanceur::CFloat4Value inputColor)
{
auto colorR = ToUint(inputColor->x() * NewFloat(b, 31.f)) << NewUint(b, 0);
auto colorG = ToUint(inputColor->y() * NewFloat(b, 31.f)) << NewUint(b, 5);
auto colorB = ToUint(inputColor->z() * NewFloat(b, 31.f)) << NewUint(b, 10);
auto colorA = ToUint(inputColor->w() * NewFloat(b, 255.f)) >> NewUint(b, 7) << NewUint(b, 15);
return colorR | colorG | colorB | colorA;
}
Nuanceur::CInt4Rvalue CMemoryUtils::PSM32ToIVec4(Nuanceur::CShaderBuilder& b, Nuanceur::CUintValue inputColor)
{
auto colorR = (inputColor >> NewUint(b, 0)) & NewUint(b, 0xFF);
auto colorG = (inputColor >> NewUint(b, 8)) & NewUint(b, 0xFF);
auto colorB = (inputColor >> NewUint(b, 16)) & NewUint(b, 0xFF);
auto colorA = (inputColor >> NewUint(b, 24)) & NewUint(b, 0xFF);
auto colorFloatR = ToInt(colorR);
auto colorFloatG = ToInt(colorG);
auto colorFloatB = ToInt(colorB);
auto colorFloatA = ToInt(colorA);
return NewInt4(colorFloatR, colorFloatG, colorFloatB, colorFloatA);
}
Nuanceur::CInt4Rvalue CMemoryUtils::PSM16ToIVec4(Nuanceur::CShaderBuilder& b, Nuanceur::CUintValue inputColor)
{
auto colorR = (inputColor >> NewUint(b, 0)) & NewUint(b, 0x1F);
auto colorG = (inputColor >> NewUint(b, 5)) & NewUint(b, 0x1F);
auto colorB = (inputColor >> NewUint(b, 10)) & NewUint(b, 0x1F);
auto colorA = (inputColor >> NewUint(b, 15)) & NewUint(b, 0x1);
auto colorFloatR = ToInt(colorR) * NewInt(b, 8);
auto colorFloatG = ToInt(colorG) * NewInt(b, 8);
auto colorFloatB = ToInt(colorB) * NewInt(b, 8);
auto colorFloatA = ToInt(colorA) * NewInt(b, 128);
return NewInt4(colorFloatR, colorFloatG, colorFloatB, colorFloatA);
}
Nuanceur::CUintRvalue CMemoryUtils::IVec4ToPSM32(Nuanceur::CShaderBuilder& b, Nuanceur::CInt4Value inputColor)
{
auto colorR = ToUint(inputColor->x()) << NewUint(b, 0);
auto colorG = ToUint(inputColor->y()) << NewUint(b, 8);
auto colorB = ToUint(inputColor->z()) << NewUint(b, 16);
auto colorA = ToUint(inputColor->w()) << NewUint(b, 24);
return colorR | colorG | colorB | colorA;
}
Nuanceur::CUintRvalue CMemoryUtils::IVec4ToPSM16(Nuanceur::CShaderBuilder& b, Nuanceur::CInt4Value inputColor)
{
auto colorR = ToUint(inputColor->x()) >> NewUint(b, 3) << NewUint(b, 0);
auto colorG = ToUint(inputColor->y()) >> NewUint(b, 3) << NewUint(b, 5);
auto colorB = ToUint(inputColor->z()) >> NewUint(b, 3) << NewUint(b, 10);
auto colorA = ToUint(inputColor->w()) >> NewUint(b, 7) << NewUint(b, 15);
return colorR | colorG | colorB | colorA;
}