mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-27 05:16:56 +01:00
shader: give an A16 bias its own address VGPR
Co-authored-by: shadowbeat070 <70843316+shadowbeat070@users.noreply.github.com>
This commit is contained in:
@@ -320,27 +320,15 @@ uint32_t CountDmaskComponents(uint32_t dmask) {
|
|||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
ImageAddressComponent ImageAddressComponentLayout(uint32_t flags, uint32_t component) {
|
ImageAddressComponent ImageAddressComponentLayout(uint32_t flags, uint32_t component) {
|
||||||
const auto width = [flags](uint32_t index) {
|
if ((flags & ImageSampleFlagA16) == 0u) return {component * 32u, 32u};
|
||||||
if ((flags & ImageSampleFlagA16) == 0u) return 32u;
|
// A16 offsets, bias and PCF reference each take a whole VGPR, the bias as a half in its low
|
||||||
uint32_t cursor = 0;
|
// 16 bits; the components after them pack two per VGPR.
|
||||||
if ((flags & ImageSampleFlagOffset) != 0u) {
|
const bool has_bias = (flags & ImageSampleFlagBias) != 0u;
|
||||||
if (index == cursor++) return 32u;
|
const uint32_t bias_index = (flags & ImageSampleFlagOffset) != 0u ? 1u : 0u;
|
||||||
}
|
const uint32_t whole_vgprs = std::popcount(
|
||||||
if ((flags & ImageSampleFlagBias) != 0u) {
|
flags & (ImageSampleFlagOffset | ImageSampleFlagBias | ImageSampleFlagCompare));
|
||||||
if (index == cursor++) return 16u;
|
if (component >= whole_vgprs) return {(whole_vgprs + component) * 16u, 16u};
|
||||||
}
|
return {component * 32u, has_bias && component == bias_index ? 16u : 32u};
|
||||||
if ((flags & ImageSampleFlagCompare) != 0u && index == cursor) return 32u;
|
|
||||||
return 16u;
|
|
||||||
};
|
|
||||||
uint32_t offset = 0;
|
|
||||||
for (uint32_t index = 0; index < component; index++) {
|
|
||||||
const auto bits = width(index);
|
|
||||||
if (bits == 32u) offset = (offset + 31u) & ~31u;
|
|
||||||
offset += bits;
|
|
||||||
}
|
|
||||||
const auto bits = width(component);
|
|
||||||
if (bits == 32u) offset = (offset + 31u) & ~31u;
|
|
||||||
return {offset, bits};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t ImageAddressDwordCount(uint32_t flags, uint32_t components) {
|
uint32_t ImageAddressDwordCount(uint32_t flags, uint32_t components) {
|
||||||
|
|||||||
@@ -40015,6 +40015,46 @@ TestCase ImageSampleA16CompareBiasRdna2AddressOrder() {
|
|||||||
return test;
|
return test;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u32 RampTexel(u32 x, u32 y) { return std::bit_cast<u32>(float(1u + x + y * 4u)); }
|
||||||
|
|
||||||
|
std::vector<u32> MakeRampImage() {
|
||||||
|
auto image = MakeRgbaImage(4, 4);
|
||||||
|
for (u32 y = 0; y < 4u; y++) {
|
||||||
|
for (u32 x = 0; x < 4u; x++) {
|
||||||
|
SetRgbaPixel(&image, 4, x, y, RampTexel(x, y), 0, 0, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return image;
|
||||||
|
}
|
||||||
|
|
||||||
|
TestCase ImageA16BiasTakesWholeVgpr() {
|
||||||
|
using O = ShaderOpcode;
|
||||||
|
TestCase test;
|
||||||
|
test.name = "ImageA16BiasTakesWholeVgpr";
|
||||||
|
// The high half of the bias VGPR holds 0.0625, which would move the coordinates if read as one.
|
||||||
|
AppendVMovLiteral(&test.code, 20, 0x2c000000u); // bias 0
|
||||||
|
AppendVMovLiteral(&test.code, 21, 0x36003900u); // x=0.625, y=0.375: texel (2, 1)
|
||||||
|
test.code.push_back(EncodeMimg0(0x25, 0x1)); // image_sample_b
|
||||||
|
test.code.push_back(EncodeMimg1(0, 20, 0, 0, true));
|
||||||
|
AppendStoreVgpr(&test.code, 0, 0);
|
||||||
|
test.expected.push_back(RampTexel(2, 1));
|
||||||
|
AppendVMovLiteral(&test.code, 22, 0x2c000000u); // bias 0
|
||||||
|
AppendVMovLiteral(&test.code, 23, 0x37003980u); // x=0.6875, y=0.4375: x 2..3, y 1..2
|
||||||
|
test.code.push_back(EncodeMimg0(0x45, 0x1)); // image_gather4_b
|
||||||
|
test.code.push_back(EncodeMimg1(4, 22, 0, 0, true));
|
||||||
|
for (u32 component = 0; component < 4u; component++) {
|
||||||
|
AppendStoreVgpr(&test.code, 4u + component, 1u + component);
|
||||||
|
}
|
||||||
|
for (const auto [x, y] : {std::pair{2u, 2u}, {3u, 2u}, {3u, 1u}, {2u, 1u}}) {
|
||||||
|
test.expected.push_back(RampTexel(x, y));
|
||||||
|
}
|
||||||
|
AppendEnd(&test.code);
|
||||||
|
test.opcodes = {O::V_MOV_B32, O::IMAGE_SAMPLE, O::IMAGE_GATHER4, O::BUFFER_STORE_DWORD,
|
||||||
|
O::S_ENDPGM};
|
||||||
|
test.sampled_image_rgba = MakeRampImage();
|
||||||
|
return test;
|
||||||
|
}
|
||||||
|
|
||||||
TestCase ImageGatherAddressVariants() {
|
TestCase ImageGatherAddressVariants() {
|
||||||
using O = ShaderOpcode;
|
using O = ShaderOpcode;
|
||||||
struct Gather {
|
struct Gather {
|
||||||
@@ -40035,13 +40075,6 @@ TestCase ImageGatherAddressVariants() {
|
|||||||
{0xd1, true, false, true}, {0xd5, true, true, false},
|
{0xd1, true, false, true}, {0xd5, true, true, false},
|
||||||
{0xd6, true, true, true},
|
{0xd6, true, true, true},
|
||||||
};
|
};
|
||||||
const auto texel = [](u32 x, u32 y) { return std::bit_cast<u32>(float(1u + x + y * 4u)); };
|
|
||||||
auto image = MakeRgbaImage(4, 4);
|
|
||||||
for (u32 y = 0; y < 4u; y++) {
|
|
||||||
for (u32 x = 0; x < 4u; x++) {
|
|
||||||
SetRgbaPixel(&image, 4, x, y, texel(x, y), 0, 0, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
TestCase test;
|
TestCase test;
|
||||||
test.name = "ImageGatherAddressVariants";
|
test.name = "ImageGatherAddressVariants";
|
||||||
for (u32 index = 0; index < std::size(gathers); index++) {
|
for (u32 index = 0; index < std::size(gathers); index++) {
|
||||||
@@ -40062,13 +40095,13 @@ TestCase ImageGatherAddressVariants() {
|
|||||||
// (x0, y0) order.
|
// (x0, y0) order.
|
||||||
const u32 x0 = gather.offset ? 1u : 2u;
|
const u32 x0 = gather.offset ? 1u : 2u;
|
||||||
for (const auto [x, y] : {std::pair{x0, 2u}, {x0 + 1u, 2u}, {x0 + 1u, 1u}, {x0, 1u}}) {
|
for (const auto [x, y] : {std::pair{x0, 2u}, {x0 + 1u, 2u}, {x0 + 1u, 1u}, {x0, 1u}}) {
|
||||||
test.expected.push_back(texel(x, y));
|
test.expected.push_back(RampTexel(x, y));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
AppendEnd(&test.code);
|
AppendEnd(&test.code);
|
||||||
test.opcodes = {O::V_MOV_B32, O::IMAGE_GATHER4, O::BUFFER_STORE_DWORD,
|
test.opcodes = {O::V_MOV_B32, O::IMAGE_GATHER4, O::BUFFER_STORE_DWORD,
|
||||||
O::S_ENDPGM};
|
O::S_ENDPGM};
|
||||||
test.sampled_image_rgba = image;
|
test.sampled_image_rgba = MakeRampImage();
|
||||||
return test;
|
return test;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -45901,6 +45934,7 @@ std::vector<TestCase> MakeCases() {
|
|||||||
AddCase(ImageSampleOffsetsReadFourNeighbors<32>);
|
AddCase(ImageSampleOffsetsReadFourNeighbors<32>);
|
||||||
AddCase(ImageSampleOffsetsReadFourNeighbors<64>);
|
AddCase(ImageSampleOffsetsReadFourNeighbors<64>);
|
||||||
AddCase(ImageSampleA16CompareBiasRdna2AddressOrder);
|
AddCase(ImageSampleA16CompareBiasRdna2AddressOrder);
|
||||||
|
AddCase(ImageA16BiasTakesWholeVgpr);
|
||||||
AddCase(ImageGatherCompareOpcodes);
|
AddCase(ImageGatherCompareOpcodes);
|
||||||
AddCase(ImageStoreVariants);
|
AddCase(ImageStoreVariants);
|
||||||
AddCase(ImageD16StoreUnpacksHalfPairs);
|
AddCase(ImageD16StoreUnpacksHalfPairs);
|
||||||
@@ -52379,6 +52413,7 @@ int main(int argc, char **argv) {
|
|||||||
RunCase(&vulkan, ImageSampleA16OffsetKeepsTexelOffset32BitOnGpu<64>());
|
RunCase(&vulkan, ImageSampleA16OffsetKeepsTexelOffset32BitOnGpu<64>());
|
||||||
RunCase(&vulkan, ImageSampleAndGather());
|
RunCase(&vulkan, ImageSampleAndGather());
|
||||||
RunCase(&vulkan, ImageGatherAddressVariants());
|
RunCase(&vulkan, ImageGatherAddressVariants());
|
||||||
|
RunCase(&vulkan, ImageA16BiasTakesWholeVgpr());
|
||||||
RunCase(nullptr, ImageGatherCompareOpcodes());
|
RunCase(nullptr, ImageGatherCompareOpcodes());
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user