mirror of
https://github.com/PCSX2/pcsx2.git
synced 2026-01-31 01:15:24 +01:00
Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b6930c10b9 | ||
|
|
852734580d | ||
|
|
d1dc6a9c1d |
@@ -12927,7 +12927,7 @@ SLAJ-25041:
|
||||
name: "Harry Potter and the Prisoner of Azkaban"
|
||||
region: "NTSC-C"
|
||||
gsHWFixes:
|
||||
cpuFramebufferConversion: 1 # Fixes right side of the screen from garbage textures.
|
||||
textureInsideRT: 1 # Fixes right side shadow lookup.
|
||||
halfPixelOffset: 2 # Aligns mirror reflections, removes some bloom-related ghosting.
|
||||
recommendedBlendingLevel: 4 # Improves lighting effects.
|
||||
SLAJ-25042:
|
||||
@@ -16829,7 +16829,7 @@ SLES-51192:
|
||||
- EETimingHack # Fixes flickering textures.
|
||||
gsHWFixes:
|
||||
recommendedBlendingLevel: 4 # Fixes missing lighting effects.
|
||||
cpuFramebufferConversion: 1 # Fixes right side of the screen from garbage textures.
|
||||
textureInsideRT: 1 # Fixes right side shadow lookup.
|
||||
halfPixelOffset: 2 # Fixes misaligned lighting and other effects.
|
||||
texturePreloading: 0 # Performs better on certain areas like mid-game in and around the castle as the hash goes easily to 200 MB.
|
||||
SLES-51193:
|
||||
@@ -16839,7 +16839,7 @@ SLES-51193:
|
||||
- EETimingHack # Fixes flickering textures.
|
||||
gsHWFixes:
|
||||
recommendedBlendingLevel: 4 # Fixes missing lighting effects.
|
||||
cpuFramebufferConversion: 1 # Fixes right side of the screen from garbage textures.
|
||||
textureInsideRT: 1 # Fixes right side shadow lookup.
|
||||
halfPixelOffset: 2 # Fixes misaligned lighting and other effects.
|
||||
texturePreloading: 0 # Performs better on certain areas like mid-game in and around the castle as the hash goes easily to 200 MB.
|
||||
SLES-51194:
|
||||
@@ -16849,7 +16849,7 @@ SLES-51194:
|
||||
- EETimingHack # Fixes flickering textures.
|
||||
gsHWFixes:
|
||||
recommendedBlendingLevel: 4 # Fixes missing lighting effects.
|
||||
cpuFramebufferConversion: 1 # Fixes right side of the screen from garbage textures.
|
||||
textureInsideRT: 1 # Fixes right side shadow lookup.
|
||||
halfPixelOffset: 2 # Fixes misaligned lighting and other effects.
|
||||
texturePreloading: 0 # Performs better on certain areas like mid-game in and around the castle as the hash goes easily to 200 MB.
|
||||
SLES-51195:
|
||||
@@ -16859,7 +16859,7 @@ SLES-51195:
|
||||
- EETimingHack # Fixes flickering textures.
|
||||
gsHWFixes:
|
||||
recommendedBlendingLevel: 4 # Fixes missing lighting effects.
|
||||
cpuFramebufferConversion: 1 # Fixes right side of the screen from garbage textures.
|
||||
textureInsideRT: 1 # Fixes right side shadow lookup.
|
||||
halfPixelOffset: 2 # Fixes misaligned lighting and other effects.
|
||||
texturePreloading: 0 # Performs better on certain areas like mid-game in and around the castle as the hash goes easily to 200 MB.
|
||||
SLES-51196:
|
||||
@@ -16869,7 +16869,7 @@ SLES-51196:
|
||||
- EETimingHack # Fixes flickering textures.
|
||||
gsHWFixes:
|
||||
recommendedBlendingLevel: 4 # Fixes missing lighting effects.
|
||||
cpuFramebufferConversion: 1 # Fixes right side of the screen from garbage textures.
|
||||
textureInsideRT: 1 # Fixes right side shadow lookup.
|
||||
halfPixelOffset: 2 # Fixes misaligned lighting and other effects.
|
||||
texturePreloading: 0 # Performs better on certain areas like mid-game in and around the castle as the hash goes easily to 200 MB.
|
||||
SLES-51197:
|
||||
@@ -16926,7 +16926,7 @@ SLES-51214:
|
||||
- EETimingHack # Fixes flickering textures.
|
||||
gsHWFixes:
|
||||
recommendedBlendingLevel: 4 # Fixes missing lighting effects.
|
||||
cpuFramebufferConversion: 1 # Fixes right side of the screen from garbage textures.
|
||||
textureInsideRT: 1 # Fixes right side shadow lookup.
|
||||
halfPixelOffset: 2 # Fixes misaligned lighting and other effects.
|
||||
texturePreloading: 0 # Performs better on certain areas like mid-game in and around the castle as the hash goes easily to 200 MB.
|
||||
SLES-51215:
|
||||
@@ -16936,7 +16936,7 @@ SLES-51215:
|
||||
- EETimingHack # Fixes flickering textures.
|
||||
gsHWFixes:
|
||||
recommendedBlendingLevel: 4 # Fixes missing lighting effects.
|
||||
cpuFramebufferConversion: 1 # Fixes right side of the screen from garbage textures.
|
||||
textureInsideRT: 1 # Fixes right side shadow lookup.
|
||||
halfPixelOffset: 2 # Fixes misaligned lighting and other effects.
|
||||
texturePreloading: 0 # Performs better on certain areas like mid-game in and around the castle as the hash goes easily to 200 MB.
|
||||
SLES-51216:
|
||||
@@ -16946,7 +16946,7 @@ SLES-51216:
|
||||
- EETimingHack # Fixes flickering textures.
|
||||
gsHWFixes:
|
||||
recommendedBlendingLevel: 4 # Fixes missing lighting effects.
|
||||
cpuFramebufferConversion: 1 # Fixes right side of the screen from garbage textures.
|
||||
textureInsideRT: 1 # Fixes right side shadow lookup.
|
||||
halfPixelOffset: 2 # Fixes misaligned lighting and other effects.
|
||||
texturePreloading: 0 # Performs better on certain areas like mid-game in and around the castle as the hash goes easily to 200 MB.
|
||||
SLES-51217:
|
||||
@@ -16956,7 +16956,7 @@ SLES-51217:
|
||||
- EETimingHack # Fixes flickering textures.
|
||||
gsHWFixes:
|
||||
recommendedBlendingLevel: 4 # Fixes missing lighting effects.
|
||||
cpuFramebufferConversion: 1 # Fixes right side of the screen from garbage textures.
|
||||
textureInsideRT: 1 # Fixes right side shadow lookup.
|
||||
halfPixelOffset: 2 # Fixes misaligned lighting and other effects.
|
||||
texturePreloading: 0 # Performs better on certain areas like mid-game in and around the castle as the hash goes easily to 200 MB.
|
||||
SLES-51218:
|
||||
@@ -16966,7 +16966,7 @@ SLES-51218:
|
||||
- EETimingHack # Fixes flickering textures.
|
||||
gsHWFixes:
|
||||
recommendedBlendingLevel: 4 # Fixes missing lighting effects.
|
||||
cpuFramebufferConversion: 1 # Fixes right side of the screen from garbage textures.
|
||||
textureInsideRT: 1 # Fixes right side shadow lookup.
|
||||
halfPixelOffset: 2 # Fixes misaligned lighting and other effects.
|
||||
texturePreloading: 0 # Performs better on certain areas like mid-game in and around the castle as the hash goes easily to 200 MB.
|
||||
SLES-51219:
|
||||
@@ -16976,7 +16976,7 @@ SLES-51219:
|
||||
- EETimingHack # Fixes flickering textures.
|
||||
gsHWFixes:
|
||||
recommendedBlendingLevel: 4 # Fixes missing lighting effects.
|
||||
cpuFramebufferConversion: 1 # Fixes right side of the screen from garbage textures.
|
||||
textureInsideRT: 1 # Fixes right side shadow lookup.
|
||||
halfPixelOffset: 2 # Fixes misaligned lighting and other effects.
|
||||
texturePreloading: 0 # Performs better on certain areas like mid-game in and around the castle as the hash goes easily to 200 MB.
|
||||
SLES-51220:
|
||||
@@ -19896,7 +19896,7 @@ SLES-52440:
|
||||
region: "PAL-M7"
|
||||
compat: 3
|
||||
gsHWFixes:
|
||||
cpuFramebufferConversion: 1 # Fixes right side of the screen from garbage textures.
|
||||
textureInsideRT: 1 # Fixes right side shadow lookup.
|
||||
halfPixelOffset: 2 # Aligns mirror reflections, removes some bloom-related ghosting.
|
||||
recommendedBlendingLevel: 4 # Improves lighting effects.
|
||||
SLES-52444:
|
||||
@@ -20123,7 +20123,7 @@ SLES-52527:
|
||||
name: "Harry Potter og Fangen fra Azkaban"
|
||||
region: "PAL-M4"
|
||||
gsHWFixes:
|
||||
cpuFramebufferConversion: 1 # Fixes right side of the screen from garbage textures.
|
||||
textureInsideRT: 1 # Fixes right side shadow lookup.
|
||||
halfPixelOffset: 2 # Aligns mirror reflections, removes some bloom-related ghosting.
|
||||
recommendedBlendingLevel: 4 # Improves lighting effects.
|
||||
SLES-52531:
|
||||
@@ -20434,7 +20434,7 @@ SLES-52600:
|
||||
name: "Harry Potter and the Prisoner of Azkaban"
|
||||
region: "PAL-PL"
|
||||
gsHWFixes:
|
||||
cpuFramebufferConversion: 1 # Fixes right side of the screen from garbage textures.
|
||||
textureInsideRT: 1 # Fixes right side shadow lookup.
|
||||
halfPixelOffset: 2 # Aligns mirror reflections, removes some bloom-related ghosting.
|
||||
recommendedBlendingLevel: 4 # Improves lighting effects.
|
||||
SLES-52601:
|
||||
@@ -31108,7 +31108,7 @@ SLKA-25172:
|
||||
name: "Harry Potter and the Prisoner of Azkaban"
|
||||
region: "NTSC-K"
|
||||
gsHWFixes:
|
||||
cpuFramebufferConversion: 1 # Fixes right side of the screen from garbage textures.
|
||||
textureInsideRT: 1 # Fixes right side shadow lookup.
|
||||
halfPixelOffset: 2 # Aligns mirror reflections, removes some bloom-related ghosting.
|
||||
recommendedBlendingLevel: 4 # Improves lighting effects.
|
||||
SLKA-25173:
|
||||
@@ -36957,7 +36957,7 @@ SLPM-62241:
|
||||
- EETimingHack # Fixes flickering textures.
|
||||
gsHWFixes:
|
||||
recommendedBlendingLevel: 4 # Fixes missing lighting effects.
|
||||
cpuFramebufferConversion: 1 # Fixes right side of the screen from garbage textures.
|
||||
textureInsideRT: 1 # Fixes right side shadow lookup.
|
||||
halfPixelOffset: 2 # Fixes misaligned lighting and other effects.
|
||||
SLPM-62242:
|
||||
name: "撞球 ビリヤードマスター2"
|
||||
@@ -38369,7 +38369,7 @@ SLPM-62513:
|
||||
- EETimingHack # Fixes flickering textures.
|
||||
gsHWFixes:
|
||||
recommendedBlendingLevel: 4 # Fixes missing lighting effects.
|
||||
cpuFramebufferConversion: 1 # Fixes right side of the screen from garbage textures.
|
||||
textureInsideRT: 1 # Fixes right side shadow lookup.
|
||||
halfPixelOffset: 2 # Fixes misaligned lighting and other effects.
|
||||
SLPM-62514:
|
||||
name: "シムピープル ~お茶の間劇場~ [EA BEST HITS]"
|
||||
@@ -39800,7 +39800,7 @@ SLPM-64528:
|
||||
- EETimingHack # Fixes flickering textures.
|
||||
gsHWFixes:
|
||||
recommendedBlendingLevel: 4 # Fixes missing lighting effects.
|
||||
cpuFramebufferConversion: 1 # Fixes right side of the screen from garbage textures.
|
||||
textureInsideRT: 1 # Fixes right side shadow lookup.
|
||||
halfPixelOffset: 2 # Fixes misaligned lighting and other effects.
|
||||
SLPM-64532:
|
||||
name: "Digital Holmes"
|
||||
@@ -43355,7 +43355,7 @@ SLPM-65612:
|
||||
name-en: "Harry Potter and the Prisoner of Azkaban"
|
||||
region: "NTSC-J"
|
||||
gsHWFixes:
|
||||
cpuFramebufferConversion: 1 # Fixes right side of the screen from garbage textures.
|
||||
textureInsideRT: 1 # Fixes right side shadow lookup.
|
||||
halfPixelOffset: 2 # Aligns mirror reflections, removes some bloom-related ghosting.
|
||||
recommendedBlendingLevel: 4 # Improves lighting effects.
|
||||
SLPM-65613:
|
||||
@@ -52157,7 +52157,7 @@ SLPM-68005:
|
||||
- EETimingHack # Fixes flickering textures.
|
||||
gsHWFixes:
|
||||
recommendedBlendingLevel: 4 # Fixes missing lighting effects.
|
||||
cpuFramebufferConversion: 1 # Fixes right side of the screen from garbage textures.
|
||||
textureInsideRT: 1 # Fixes right side shadow lookup.
|
||||
halfPixelOffset: 2 # Fixes misaligned lighting and other effects.
|
||||
SLPM-68007:
|
||||
name: "カラオケレボリューション用マイク同梱お試しディスク"
|
||||
@@ -54308,7 +54308,7 @@ SLPS-20234:
|
||||
- EETimingHack # Fixes flickering textures.
|
||||
gsHWFixes:
|
||||
recommendedBlendingLevel: 4 # Fixes missing lighting effects.
|
||||
cpuFramebufferConversion: 1 # Fixes right side of the screen from garbage textures.
|
||||
textureInsideRT: 1 # Fixes right side shadow lookup.
|
||||
halfPixelOffset: 2 # Fixes misaligned lighting and other effects.
|
||||
SLPS-20237:
|
||||
name: "Saikyou Toudai Shougi 3"
|
||||
@@ -65273,7 +65273,7 @@ SLUS-20576:
|
||||
- EETimingHack # Fixes flickering textures.
|
||||
gsHWFixes:
|
||||
recommendedBlendingLevel: 4 # Fixes missing lighting effects.
|
||||
cpuFramebufferConversion: 1 # Fixes right side of the screen from garbage textures.
|
||||
textureInsideRT: 1 # Fixes right side shadow lookup.
|
||||
halfPixelOffset: 2 # Fixes misaligned lighting and other effects.
|
||||
SLUS-20577:
|
||||
name: "Drome Racers"
|
||||
@@ -67218,7 +67218,7 @@ SLUS-20926:
|
||||
name: "Harry Potter and the Prisoner of Azkaban"
|
||||
region: "NTSC-U"
|
||||
gsHWFixes:
|
||||
cpuFramebufferConversion: 1 # Fixes right side of the screen from garbage textures.
|
||||
textureInsideRT: 1 # Fixes right side shadow lookup.
|
||||
halfPixelOffset: 2 # Aligns mirror reflections, removes some bloom-related ghosting.
|
||||
recommendedBlendingLevel: 4 # Improves lighting effects.
|
||||
SLUS-20927:
|
||||
|
||||
@@ -313,6 +313,127 @@ float ps_convert_rgb5a1_float16_biln(PS_INPUT input) : SV_Depth
|
||||
SAMPLE_RGBA_DEPTH_BILN(rgb5a1_to_depth16);
|
||||
}
|
||||
|
||||
PS_OUTPUT ps_convert_rgb5a1_8i(PS_INPUT input)
|
||||
{
|
||||
PS_OUTPUT output;
|
||||
|
||||
// Convert a RGB5A1 texture into a 8 bits packed texture
|
||||
// Input column: 16x2 RGB5A1 pixels
|
||||
// 0: 16 RGBA
|
||||
// 1: 16 RGBA
|
||||
// Output column: 16x4 Index pixels
|
||||
// 0: 16 R5G2
|
||||
// 1: 16 R5G2
|
||||
// 2: 16 G2B5A1
|
||||
// 3: 16 G2B5A1
|
||||
uint2 pos = uint2(input.p.xy);
|
||||
|
||||
// Collapse separate R G B A areas into their base pixel
|
||||
uint2 column = (pos & ~uint2(0u, 3u)) / uint2(1,2);
|
||||
uint2 subcolumn = (pos & uint2(0u, 1u));
|
||||
column.x -= (column.x / 128) * 64;
|
||||
column.y += (column.y / 32) * 32;
|
||||
|
||||
uint PSM = uint(DOFFSET);
|
||||
|
||||
// Deal with swizzling differences
|
||||
if ((PSM & 0x8) != 0) // PSMCT16S
|
||||
{
|
||||
if ((pos.x & 32) != 0)
|
||||
{
|
||||
column.y += 32; // 4 columns high times 4 to get bottom 4 blocks
|
||||
column.x &= ~32;
|
||||
}
|
||||
|
||||
if ((pos.x & 64) != 0)
|
||||
{
|
||||
column.x -= 32;
|
||||
}
|
||||
|
||||
if (((pos.x & 16) != 0) != ((pos.y & 16) != 0))
|
||||
{
|
||||
column.x ^= 16;
|
||||
column.y ^= 8;
|
||||
}
|
||||
|
||||
if ((PSM & 0x30) != 0) // PSMZ16S - Untested but hopefully ok if anything uses it.
|
||||
{
|
||||
column.x ^= 32;
|
||||
column.y ^= 16;
|
||||
}
|
||||
}
|
||||
else // PSMCT16
|
||||
{
|
||||
if ((pos.y & 32) != 0)
|
||||
{
|
||||
column.y -= 16;
|
||||
column.x += 32;
|
||||
}
|
||||
|
||||
if ((pos.x & 96) != 0)
|
||||
{
|
||||
uint multi = (pos.x & 96) / 32;
|
||||
column.y += 16 * multi; // 4 columns high times 4 to get bottom 4 blocks
|
||||
column.x -= (pos.x & 96);
|
||||
}
|
||||
|
||||
if (((pos.x & 16) != 0) != ((pos.y & 16) != 0))
|
||||
{
|
||||
column.x ^= 16;
|
||||
column.y ^= 8;
|
||||
}
|
||||
|
||||
if ((PSM & 0x30) != 0) // PSMZ16 - Untested but hopefully ok if anything uses it.
|
||||
{
|
||||
column.x ^= 32;
|
||||
column.y ^= 32;
|
||||
}
|
||||
}
|
||||
|
||||
uint2 coord = column | subcolumn;
|
||||
|
||||
// Compensate for potentially differing page pitch.
|
||||
uint SBW = uint(EMODA);
|
||||
uint DBW = uint(EMODC);
|
||||
uint2 block_xy = coord / uint2(64,64);
|
||||
uint block_num = (block_xy.y * (DBW / 128)) + block_xy.x;
|
||||
uint2 block_offset = uint2((block_num % (SBW / 64)) * 64, (block_num / (SBW / 64)) * 64);
|
||||
coord = (coord % uint2(64, 64)) + block_offset;
|
||||
|
||||
// Apply offset to cols 1 and 2
|
||||
uint is_col23 = pos.y & 4u;
|
||||
uint is_col13 = pos.y & 2u;
|
||||
uint is_col12 = is_col23 ^ (is_col13 << 1);
|
||||
coord.x ^= is_col12; // If cols 1 or 2, flip bit 3 of x
|
||||
|
||||
float ScaleFactor = BGColor.x;
|
||||
if (floor(ScaleFactor) != ScaleFactor)
|
||||
coord = uint2(float2(coord) * ScaleFactor);
|
||||
else
|
||||
coord *= uint(ScaleFactor);
|
||||
|
||||
float4 pixel = Texture.Load(int3(int2(coord), 0));
|
||||
uint4 denorm_c = (uint4)(pixel * 255.5f);
|
||||
if ((pos.y & 2u) == 0u)
|
||||
{
|
||||
uint red = (denorm_c.r >> 3) & 0x1Fu;
|
||||
uint green = (denorm_c.g >> 3) & 0x1Fu;
|
||||
float sel0 = (float)(((green << 5) | red) & 0xFF) / 255.0f;
|
||||
|
||||
output.c = (float4)(sel0);
|
||||
}
|
||||
else
|
||||
{
|
||||
uint green = (denorm_c.g >> 3) & 0x1Fu;
|
||||
uint blue = (denorm_c.b >> 3) & 0x1Fu;
|
||||
uint alpha = denorm_c.a & 0x80u;
|
||||
float sel0 = (float)((alpha | (blue << 2) | (green >> 3)) & 0xFF) / 255.0f;
|
||||
|
||||
output.c = (float4)(sel0);
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
PS_OUTPUT ps_convert_rgba_8i(PS_INPUT input)
|
||||
{
|
||||
PS_OUTPUT output;
|
||||
|
||||
@@ -237,9 +237,131 @@ void ps_convert_rgb5a1_float16_biln()
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef ps_convert_rgb5a1_8i
|
||||
uniform uint SBW;
|
||||
uniform uint DBW;
|
||||
uniform uint PSM;
|
||||
uniform float ScaleFactor;
|
||||
|
||||
void ps_convert_rgb5a1_8i()
|
||||
{
|
||||
// Convert a RGB5A1 texture into a 8 bits packed texture
|
||||
// Input column: 16x2 RGB5A1 pixels
|
||||
// 0: 16 RGBA
|
||||
// 1: 16 RGBA
|
||||
// Output column: 16x4 Index pixels
|
||||
// 0: 16 R5G2
|
||||
// 1: 16 R5G2
|
||||
// 2: 16 G2B5A1
|
||||
// 3: 16 G2B5A1
|
||||
|
||||
uvec2 pos = uvec2(gl_FragCoord.xy);
|
||||
|
||||
// Collapse separate R G B A areas into their base pixel
|
||||
uvec2 column = (pos & ~uvec2(0u, 3u)) / uvec2(1,2);
|
||||
uvec2 subcolumn = (pos & uvec2(0u, 1u));
|
||||
column.x -= (column.x / 128) * 64;
|
||||
column.y += (column.y / 32) * 32;
|
||||
|
||||
// Deal with swizzling differences
|
||||
if ((PSM & 0x8) != 0) // PSMCT16S
|
||||
{
|
||||
if ((pos.x & 32) != 0)
|
||||
{
|
||||
column.y += 32; // 4 columns high times 4 to get bottom 4 blocks
|
||||
column.x &= ~32;
|
||||
}
|
||||
|
||||
if ((pos.x & 64) != 0)
|
||||
{
|
||||
column.x -= 32;
|
||||
}
|
||||
|
||||
if (((pos.x & 16) != 0) != ((pos.y & 16) != 0))
|
||||
{
|
||||
column.x ^= 16;
|
||||
column.y ^= 8;
|
||||
}
|
||||
|
||||
if ((PSM & 0x30) != 0) // PSMZ16S - Untested but hopefully ok if anything uses it.
|
||||
{
|
||||
column.x ^= 32;
|
||||
column.y ^= 16;
|
||||
}
|
||||
}
|
||||
else // PSMCT16
|
||||
{
|
||||
if ((pos.y & 32) != 0)
|
||||
{
|
||||
column.y -= 16;
|
||||
column.x += 32;
|
||||
}
|
||||
|
||||
if ((pos.x & 96) != 0)
|
||||
{
|
||||
uint multi = (pos.x & 96) / 32;
|
||||
column.y += 16 * multi; // 4 columns high times 4 to get bottom 4 blocks
|
||||
column.x -= (pos.x & 96);
|
||||
}
|
||||
|
||||
if (((pos.x & 16) != 0) != ((pos.y & 16) != 0))
|
||||
{
|
||||
column.x ^= 16;
|
||||
column.y ^= 8;
|
||||
}
|
||||
|
||||
if ((PSM & 0x30) != 0) // PSMZ16 - Untested but hopefully ok if anything uses it.
|
||||
{
|
||||
column.x ^= 32;
|
||||
column.y ^= 32;
|
||||
}
|
||||
}
|
||||
uvec2 coord = column | subcolumn;
|
||||
|
||||
// Compensate for potentially differing page pitch.
|
||||
uvec2 block_xy = coord / uvec2(64u, 64u);
|
||||
uint block_num = (block_xy.y * (DBW / 128u)) + block_xy.x;
|
||||
uvec2 block_offset = uvec2((block_num % (SBW / 64u)) * 64u, (block_num / (SBW / 64u)) * 64u);
|
||||
coord = (coord % uvec2(64u, 64u)) + block_offset;
|
||||
|
||||
// Apply offset to cols 1 and 2
|
||||
uint is_col23 = pos.y & 4u;
|
||||
uint is_col13 = pos.y & 2u;
|
||||
uint is_col12 = is_col23 ^ (is_col13 << 1);
|
||||
coord.x ^= is_col12; // If cols 1 or 2, flip bit 3 of x
|
||||
|
||||
if (floor(ScaleFactor) != ScaleFactor)
|
||||
coord = uvec2(vec2(coord) * ScaleFactor);
|
||||
else
|
||||
coord *= uvec2(ScaleFactor);
|
||||
|
||||
vec4 pixel = texelFetch(TextureSampler, ivec2(coord), 0);
|
||||
|
||||
uvec4 denorm_c = uvec4(pixel * 255.5f);
|
||||
if ((pos.y & 2u) == 0u)
|
||||
{
|
||||
uint red = (denorm_c.r >> 3) & 0x1Fu;
|
||||
uint green = (denorm_c.g >> 3) & 0x1Fu;
|
||||
float sel0 = float(((green << 5) | red) & 0xFF) / 255.0f;
|
||||
|
||||
SV_Target0 = vec4(sel0);
|
||||
}
|
||||
else
|
||||
{
|
||||
uint green = (denorm_c.g >> 3) & 0x1Fu;
|
||||
uint blue = (denorm_c.b >> 3) & 0x1Fu;
|
||||
uint alpha = denorm_c.a & 0x80u;
|
||||
float sel0 = float((alpha | (blue << 2) | (green >> 3)) & 0xFF) / 255.0f;
|
||||
|
||||
SV_Target0 = vec4(sel0);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef ps_convert_rgba_8i
|
||||
uniform uint SBW;
|
||||
uniform uint DBW;
|
||||
uniform uint PSM;
|
||||
uniform float ScaleFactor;
|
||||
|
||||
void ps_convert_rgba_8i()
|
||||
|
||||
@@ -307,12 +307,138 @@ void ps_convert_rgb5a1_float16_biln()
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef ps_convert_rgb5a1_8i
|
||||
layout(push_constant) uniform cb10
|
||||
{
|
||||
uint SBW;
|
||||
uint DBW;
|
||||
uint PSM;
|
||||
float cb_pad1;
|
||||
float ScaleFactor;
|
||||
vec3 cb_pad2;
|
||||
};
|
||||
|
||||
void ps_convert_rgb5a1_8i()
|
||||
{
|
||||
// Convert a RGB5A1 texture into a 8 bits packed texture
|
||||
// Input column: 16x2 RGB5A1 pixels
|
||||
// 0: 16 RGBA
|
||||
// 1: 16 RGBA
|
||||
// Output column: 16x4 Index pixels
|
||||
// 0: 16 R5G2
|
||||
// 1: 16 R5G2
|
||||
// 2: 16 G2B5A1
|
||||
// 3: 16 G2B5A1
|
||||
|
||||
uvec2 pos = uvec2(gl_FragCoord.xy);
|
||||
|
||||
// Collapse separate R G B A areas into their base pixel
|
||||
uvec2 column = (pos & ~uvec2(0u, 3u)) / uvec2(1,2);
|
||||
uvec2 subcolumn = (pos & uvec2(0u, 1u));
|
||||
column.x -= (column.x / 128) * 64;
|
||||
column.y += (column.y / 32) * 32;
|
||||
|
||||
// Deal with swizzling differences
|
||||
if ((PSM & 0x8) != 0) // PSMCT16S
|
||||
{
|
||||
if ((pos.x & 32) != 0)
|
||||
{
|
||||
column.y += 32; // 4 columns high times 4 to get bottom 4 blocks
|
||||
column.x &= ~32;
|
||||
}
|
||||
|
||||
if ((pos.x & 64) != 0)
|
||||
{
|
||||
column.x -= 32;
|
||||
}
|
||||
|
||||
if (((pos.x & 16) != 0) != ((pos.y & 16) != 0))
|
||||
{
|
||||
column.x ^= 16;
|
||||
column.y ^= 8;
|
||||
}
|
||||
|
||||
if ((PSM & 0x30) != 0) // PSMZ16S - Untested but hopefully ok if anything uses it.
|
||||
{
|
||||
column.x ^= 32;
|
||||
column.y ^= 16;
|
||||
}
|
||||
}
|
||||
else // PSMCT16
|
||||
{
|
||||
if ((pos.y & 32) != 0)
|
||||
{
|
||||
column.y -= 16;
|
||||
column.x += 32;
|
||||
}
|
||||
|
||||
if ((pos.x & 96) != 0)
|
||||
{
|
||||
uint multi = (pos.x & 96) / 32;
|
||||
column.y += 16 * multi; // 4 columns high times 4 to get bottom 4 blocks
|
||||
column.x -= (pos.x & 96);
|
||||
}
|
||||
|
||||
if (((pos.x & 16) != 0) != ((pos.y & 16) != 0))
|
||||
{
|
||||
column.x ^= 16;
|
||||
column.y ^= 8;
|
||||
}
|
||||
|
||||
if ((PSM & 0x30) != 0) // PSMZ16 - Untested but hopefully ok if anything uses it.
|
||||
{
|
||||
column.x ^= 32;
|
||||
column.y ^= 32;
|
||||
}
|
||||
}
|
||||
uvec2 coord = column | subcolumn;
|
||||
|
||||
// Compensate for potentially differing page pitch.
|
||||
uvec2 block_xy = coord / uvec2(64u, 64u);
|
||||
uint block_num = (block_xy.y * (DBW / 128u)) + block_xy.x;
|
||||
uvec2 block_offset = uvec2((block_num % (SBW / 64u)) * 64u, (block_num / (SBW / 64u)) * 64u);
|
||||
coord = (coord % uvec2(64u, 64u)) + block_offset;
|
||||
|
||||
// Apply offset to cols 1 and 2
|
||||
uint is_col23 = pos.y & 4u;
|
||||
uint is_col13 = pos.y & 2u;
|
||||
uint is_col12 = is_col23 ^ (is_col13 << 1);
|
||||
coord.x ^= is_col12; // If cols 1 or 2, flip bit 3 of x
|
||||
|
||||
if (floor(ScaleFactor) != ScaleFactor)
|
||||
coord = uvec2(vec2(coord) * ScaleFactor);
|
||||
else
|
||||
coord *= uvec2(ScaleFactor);
|
||||
|
||||
vec4 pixel = texelFetch(samp0, ivec2(coord), 0);
|
||||
uvec4 denorm_c = uvec4(pixel * 255.5f);
|
||||
if ((pos.y & 2u) == 0u)
|
||||
{
|
||||
uint red = (denorm_c.r >> 3) & 0x1Fu;
|
||||
uint green = (denorm_c.g >> 3) & 0x1Fu;
|
||||
float sel0 = float(((green << 5) | red) & 0xFF) / 255.0f;
|
||||
|
||||
o_col0 = vec4(sel0);
|
||||
}
|
||||
else
|
||||
{
|
||||
uint green = (denorm_c.g >> 3) & 0x1Fu;
|
||||
uint blue = (denorm_c.b >> 3) & 0x1Fu;
|
||||
uint alpha = denorm_c.a & 0x80u;
|
||||
float sel0 = float((alpha | (blue << 2) | (green >> 3)) & 0xFF) / 255.0f;
|
||||
|
||||
o_col0 = vec4(sel0);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef ps_convert_rgba_8i
|
||||
layout(push_constant) uniform cb10
|
||||
{
|
||||
uint SBW;
|
||||
uint DBW;
|
||||
uvec2 cb_pad1;
|
||||
uint PSM;
|
||||
float cb_pad1;
|
||||
float ScaleFactor;
|
||||
vec3 cb_pad2;
|
||||
};
|
||||
|
||||
@@ -68,6 +68,7 @@ const char* shaderName(ShaderConvert value)
|
||||
case ShaderConvert::DEPTH_COPY: return "ps_depth_copy";
|
||||
case ShaderConvert::DOWNSAMPLE_COPY: return "ps_downsample_copy";
|
||||
case ShaderConvert::RGBA_TO_8I: return "ps_convert_rgba_8i";
|
||||
case ShaderConvert::RGB5A1_TO_8I: return "ps_convert_rgb5a1_8i";
|
||||
case ShaderConvert::CLUT_4: return "ps_convert_clut_4";
|
||||
case ShaderConvert::CLUT_8: return "ps_convert_clut_8";
|
||||
case ShaderConvert::YUV: return "ps_yuv";
|
||||
|
||||
@@ -44,6 +44,7 @@ enum class ShaderConvert
|
||||
DEPTH_COPY,
|
||||
DOWNSAMPLE_COPY,
|
||||
RGBA_TO_8I,
|
||||
RGB5A1_TO_8I,
|
||||
CLUT_4,
|
||||
CLUT_8,
|
||||
YUV,
|
||||
|
||||
@@ -1417,14 +1417,14 @@ void GSDevice11::ConvertToIndexedTexture(GSTexture* sTex, float sScale, u32 offs
|
||||
{
|
||||
float scale;
|
||||
float pad1[3];
|
||||
u32 SBW, DBW, pad3;
|
||||
u32 SBW, DBW, SPSM;
|
||||
};
|
||||
|
||||
const Uniforms cb = {sScale, {}, SBW, DBW};
|
||||
const Uniforms cb = {sScale, {}, SBW, DBW, SPSM};
|
||||
m_ctx->UpdateSubresource(m_merge.cb.get(), 0, nullptr, &cb, 0, 0);
|
||||
|
||||
const GSVector4 dRect(0, 0, dTex->GetWidth(), dTex->GetHeight());
|
||||
const ShaderConvert shader = ShaderConvert::RGBA_TO_8I;
|
||||
const ShaderConvert shader = ((SPSM & 0xE) == 0) ? ShaderConvert::RGBA_TO_8I : ShaderConvert::RGB5A1_TO_8I;
|
||||
StretchRect(sTex, GSVector4::zero(), dTex, dRect, m_convert.ps[static_cast<int>(shader)].get(), m_merge.cb.get(), nullptr, false);
|
||||
}
|
||||
|
||||
|
||||
@@ -1486,15 +1486,15 @@ void GSDevice12::ConvertToIndexedTexture(
|
||||
{
|
||||
float scale;
|
||||
float pad1[3];
|
||||
u32 SBW, DBW, pad2;
|
||||
u32 SBW, DBW, SPSM;
|
||||
};
|
||||
|
||||
const Uniforms cb = {sScale, {}, SBW, DBW};
|
||||
const Uniforms cb = {sScale, {}, SBW, DBW, SPSM};
|
||||
SetUtilityRootSignature();
|
||||
SetUtilityPushConstants(&cb, sizeof(cb));
|
||||
|
||||
const GSVector4 dRect(0, 0, dTex->GetWidth(), dTex->GetHeight());
|
||||
const ShaderConvert shader = ShaderConvert::RGBA_TO_8I;
|
||||
const ShaderConvert shader = ((SPSM & 0xE) == 0) ? ShaderConvert::RGBA_TO_8I : ShaderConvert::RGB5A1_TO_8I;
|
||||
DoStretchRect(static_cast<GSTexture12*>(sTex), GSVector4::zero(), static_cast<GSTexture12*>(dTex), dRect,
|
||||
m_convert[static_cast<int>(shader)].get(), false, true);
|
||||
}
|
||||
|
||||
@@ -1617,8 +1617,7 @@ GSTextureCache::Source* GSTextureCache::LookupSource(const bool is_color, const
|
||||
{
|
||||
const bool outside_target = !t->Overlaps(bp, bw, psm, r);
|
||||
|
||||
// We don't have a shader for this.
|
||||
if (!possible_shuffle && TEX0.PSM == PSMT8 && ((GSLocalMemory::m_psm[t->m_TEX0.PSM].bpp != 32) || outside_target))
|
||||
if (!possible_shuffle && TEX0.PSM == PSMT8 && outside_target)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@@ -1647,7 +1646,7 @@ GSTextureCache::Source* GSTextureCache::LookupSource(const bool is_color, const
|
||||
// Make sure the texture actually is INSIDE the RT, it's possibly not valid if it isn't.
|
||||
// Also check BP >= TBP, create source isn't equpped to expand it backwards and all data comes from the target. (GH3)
|
||||
else if (GSConfig.UserHacks_TextureInsideRt >= GSTextureInRtMode::InsideTargets &&
|
||||
(GSLocalMemory::m_psm[color_psm].bpp >= 16 || (/*possible_shuffle &&*/ GSLocalMemory::m_psm[color_psm].bpp == 8 && GSLocalMemory::m_psm[t->m_TEX0.PSM].bpp == 32)) && // Channel shuffles or non indexed lookups.
|
||||
(GSLocalMemory::m_psm[color_psm].bpp >= 16 || (/*possible_shuffle &&*/ GSLocalMemory::m_psm[color_psm].bpp == 8 && GSLocalMemory::m_psm[t->m_TEX0.PSM].bpp >= 16)) && // Channel shuffles or non indexed lookups.
|
||||
t->m_age <= 1 && (!found_t || t->m_last_draw > dst->m_last_draw) /*&& CanTranslate(bp, bw, psm, block_boundary_rect, t->m_TEX0.TBP0, t->m_TEX0.PSM, t->m_TEX0.TBW)*/)
|
||||
{
|
||||
u32 rt_tbw = std::max(1U, t->m_TEX0.TBW);
|
||||
@@ -1666,7 +1665,7 @@ GSTextureCache::Source* GSTextureCache::LookupSource(const bool is_color, const
|
||||
// Keep note that 2 bw is basically 1 normal page, as bw is in 64 pixels, and 8bit pages are 128 pixels wide, aka 2 bw.
|
||||
// Also check for 4HH/HL and 8H which use the alpha channel, if the page order is wrong this can cause problems as well (Jak X font).
|
||||
else if (!possible_shuffle && GSLocalMemory::m_psm[psm].trbpp <= 8 && (GSUtil::GetChannelMask(t->m_TEX0.PSM) != 0xF ||
|
||||
(GSLocalMemory::m_psm[t->m_TEX0.PSM].bpp == 32 && (!(block_boundary_rect.w <= GSLocalMemory::m_psm[psm].pgs.y &&
|
||||
((GSLocalMemory::m_psm[t->m_TEX0.PSM].bpp != 16 || GSLocalMemory::m_psm[psm].bpp < 16) && (!(block_boundary_rect.w <= GSLocalMemory::m_psm[psm].pgs.y &&
|
||||
((GSLocalMemory::m_psm[psm].bpp == 32) ? bw : ((bw + 1) / 2)) <= t->m_TEX0.TBW) &&
|
||||
!(((GSLocalMemory::m_psm[psm].bpp == 32) ? bw : ((bw + 1) / 2)) == rt_tbw)))))
|
||||
{
|
||||
@@ -2007,7 +2006,6 @@ GSTextureCache::Source* GSTextureCache::LookupSource(const bool is_color, const
|
||||
GL_CACHE("TC: src miss (0x%x, 0x%x, %s)", TEX0.TBP0, psm_s.pal > 0 ? TEX0.CBP : 0, psm_str(TEX0.PSM));
|
||||
}
|
||||
#endif
|
||||
|
||||
// This is for the condition where the target doesn't exist on a shuffle and it needs to load from memory.
|
||||
// The Godfather clears the depth buffer with a normal clear, so our depth target gets deleted, then because it finds no target
|
||||
// it assumes it really is 16bits, causing the texture to be full of garbage, and our shuffle handling becomes a mess.
|
||||
@@ -5667,7 +5665,7 @@ GSTextureCache::Source* GSTextureCache::CreateSource(const GIFRegTEX0& TEX0, con
|
||||
if (is_8bits)
|
||||
{
|
||||
GL_INS("TC: Reading RT as a packed-indexed 8 bits format");
|
||||
shader = ShaderConvert::RGBA_TO_8I;
|
||||
shader = GSLocalMemory::m_psm[dst->m_TEX0.PSM].bpp == 16 ? ShaderConvert::RGB5A1_TO_8I : ShaderConvert::RGBA_TO_8I;
|
||||
}
|
||||
|
||||
#ifdef ENABLE_OGL_DEBUG
|
||||
@@ -5737,7 +5735,11 @@ GSTextureCache::Source* GSTextureCache::CreateSource(const GIFRegTEX0& TEX0, con
|
||||
{
|
||||
// We're inside the target, so conversion needs to happen on the entire target so we can offset properly.
|
||||
src->m_unscaled_size.x = dst->m_unscaled_size.x * 2;
|
||||
src->m_unscaled_size.y = dst->m_unscaled_size.y * 2;
|
||||
if (GSLocalMemory::m_psm[dst->m_TEX0.PSM].bpp == 32)
|
||||
src->m_unscaled_size.y = dst->m_unscaled_size.y * 2;
|
||||
else
|
||||
src->m_unscaled_size.y = dst->m_unscaled_size.y;
|
||||
|
||||
new_size.x = src->m_unscaled_size.x;
|
||||
new_size.y = src->m_unscaled_size.y;
|
||||
}
|
||||
@@ -5908,7 +5910,8 @@ GSTextureCache::Source* GSTextureCache::CreateSource(const GIFRegTEX0& TEX0, con
|
||||
|
||||
// Adjust to match a PSMT8 texture (coordinates are double C32, we shouldn't be converting from anything else).
|
||||
x_offset *= 2;
|
||||
y_offset *= 2;
|
||||
if (GSLocalMemory::m_psm[dst->m_TEX0.PSM].bpp == 32)
|
||||
y_offset *= 2;
|
||||
|
||||
src->m_region.SetX(x_offset, x_offset + tw);
|
||||
src->m_region.SetY(y_offset, y_offset + th);
|
||||
@@ -6695,6 +6698,8 @@ void GSTextureCache::Read(Target* t, const GSVector4i& r)
|
||||
{
|
||||
case PSMCT32:
|
||||
case PSMCT24:
|
||||
case PSMZ32:
|
||||
case PSMZ24:
|
||||
{
|
||||
// If we're downloading a depth buffer that's been reinterpreted as a color
|
||||
// format, convert it to integer. The format/swizzle is likely wrong, but it's
|
||||
@@ -6720,27 +6725,11 @@ void GSTextureCache::Read(Target* t, const GSVector4i& r)
|
||||
|
||||
case PSMCT16:
|
||||
case PSMCT16S:
|
||||
{
|
||||
fmt = GSTexture::Format::UInt16;
|
||||
ps_shader = is_depth ? ShaderConvert::FLOAT32_TO_16_BITS : ShaderConvert::RGBA8_TO_16_BITS;
|
||||
dltex = &m_uint16_download_texture;
|
||||
}
|
||||
break;
|
||||
|
||||
case PSMZ32:
|
||||
case PSMZ24:
|
||||
{
|
||||
fmt = GSTexture::Format::UInt32;
|
||||
ps_shader = ShaderConvert::FLOAT32_TO_32_BITS;
|
||||
dltex = &m_uint32_download_texture;
|
||||
}
|
||||
break;
|
||||
|
||||
case PSMZ16:
|
||||
case PSMZ16S:
|
||||
{
|
||||
fmt = GSTexture::Format::UInt16;
|
||||
ps_shader = ShaderConvert::FLOAT32_TO_16_BITS;
|
||||
ps_shader = is_depth ? ShaderConvert::FLOAT32_TO_16_BITS : ShaderConvert::RGBA8_TO_16_BITS;
|
||||
dltex = &m_uint16_download_texture;
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -1713,12 +1713,12 @@ void GSDeviceMTL::UpdateCLUTTexture(GSTexture* sTex, float sScale, u32 offsetX,
|
||||
|
||||
void GSDeviceMTL::ConvertToIndexedTexture(GSTexture* sTex, float sScale, u32 offsetX, u32 offsetY, u32 SBW, u32 SPSM, GSTexture* dTex, u32 DBW, u32 DPSM)
|
||||
{ @autoreleasepool {
|
||||
const ShaderConvert shader = ShaderConvert::RGBA_TO_8I;
|
||||
const ShaderConvert shader = ((SPSM & 0xE) == 0) ? ShaderConvert::RGBA_TO_8I : ShaderConvert::RGB5A1_TO_8I;
|
||||
id<MTLRenderPipelineState> pipeline = m_convert_pipeline[static_cast<int>(shader)];
|
||||
if (!pipeline)
|
||||
[NSException raise:@"StretchRect Missing Pipeline" format:@"No pipeline for %d", static_cast<int>(shader)];
|
||||
|
||||
GSMTLIndexedConvertPSUniform uniform = { sScale, SBW, DBW };
|
||||
GSMTLIndexedConvertPSUniform uniform = { sScale, SBW, DBW, SPSM };
|
||||
|
||||
const GSVector4 dRect(0, 0, dTex->GetWidth(), dTex->GetHeight());
|
||||
DoStretchRect(sTex, GSVector4::zero(), dTex, dRect, pipeline, false, LoadAction::DontCareIfFull, &uniform, sizeof(uniform));
|
||||
|
||||
@@ -64,6 +64,7 @@ struct GSMTLIndexedConvertPSUniform
|
||||
float scale;
|
||||
uint sbw;
|
||||
uint dbw;
|
||||
uint psm;
|
||||
};
|
||||
|
||||
struct GSMTLDownsamplePSUniform
|
||||
|
||||
@@ -296,6 +296,121 @@ fragment DepthOut ps_convert_rgb5a1_float16_biln(ConvertShaderData data [[stage_
|
||||
return res.sample_biln<rgb5a1_to_depth16>(data.t);
|
||||
}
|
||||
|
||||
fragment float4 ps_convert_rgb5a1_8i(ConvertShaderData data [[stage_in]], DirectReadTextureIn<float> res,
|
||||
constant GSMTLIndexedConvertPSUniform& uniform [[buffer(GSMTLBufferIndexUniforms)]])
|
||||
{
|
||||
// Convert a RGB5A1 texture into a 8 bits packed texture
|
||||
// Input column: 16x2 RGB5A1 pixels
|
||||
// 0: 16 RGBA
|
||||
// 1: 16 RGBA
|
||||
// Output column: 16x4 Index pixels
|
||||
// 0: 16 R5G2
|
||||
// 1: 16 R5G2
|
||||
// 2: 16 G2B5A1
|
||||
// 3: 16 G2B5A1
|
||||
uint2 pos = uint2(data.p.xy);
|
||||
|
||||
// Collapse separate R G B A areas into their base pixel
|
||||
uint2 column = (pos & ~uint2(0u, 3u)) / uint2(1,2);
|
||||
uint2 subcolumn = (pos & uint2(0u, 1u));
|
||||
column.x -= (column.x / 128) * 64;
|
||||
column.y += (column.y / 32) * 32;
|
||||
|
||||
// Deal with swizzling differences
|
||||
if ((uniform.psm & 0x8) != 0) // PSMCT16S
|
||||
{
|
||||
if ((pos.x & 32) != 0)
|
||||
{
|
||||
column.y += 32; // 4 columns high times 4 to get bottom 4 blocks
|
||||
column.x &= ~32;
|
||||
}
|
||||
|
||||
if ((pos.x & 64) != 0)
|
||||
{
|
||||
column.x -= 32;
|
||||
}
|
||||
|
||||
if (((pos.x & 16) != 0) != ((pos.y & 16) != 0))
|
||||
{
|
||||
column.x ^= 16;
|
||||
column.y ^= 8;
|
||||
}
|
||||
|
||||
if ((uniform.psm & 0x30) != 0) // PSMZ16S - Untested but hopefully ok if anything uses it.
|
||||
{
|
||||
column.x ^= 32;
|
||||
column.y ^= 16;
|
||||
}
|
||||
}
|
||||
else // PSMCT16
|
||||
{
|
||||
if ((pos.y & 32) != 0)
|
||||
{
|
||||
column.y -= 16;
|
||||
column.x += 32;
|
||||
}
|
||||
|
||||
if ((pos.x & 96) != 0)
|
||||
{
|
||||
uint multi = (pos.x & 96) / 32;
|
||||
column.y += 16 * multi; // 4 columns high times 4 to get bottom 4 blocks
|
||||
column.x -= (pos.x & 96);
|
||||
}
|
||||
|
||||
if (((pos.x & 16) != 0) != ((pos.y & 16) != 0))
|
||||
{
|
||||
column.x ^= 16;
|
||||
column.y ^= 8;
|
||||
}
|
||||
|
||||
if ((uniform.psm & 0x30) != 0) // PSMZ16 - Untested but hopefully ok if anything uses it.
|
||||
{
|
||||
column.x ^= 32;
|
||||
column.y ^= 32;
|
||||
}
|
||||
}
|
||||
|
||||
uint2 coord = column | subcolumn;
|
||||
|
||||
// Compensate for potentially differing page pitch.
|
||||
uint2 block_xy = coord / uint2(64, 64);
|
||||
uint block_num = (block_xy.y * (uniform.dbw / 128)) + block_xy.x;
|
||||
uint2 block_offset = uint2((block_num % (uniform.sbw / 64)) * 64, (block_num / (uniform.sbw / 64)) * 64);
|
||||
coord = (coord % uint2(64, 64)) + block_offset;
|
||||
|
||||
// Apply offset to cols 1 and 2
|
||||
uint is_col23 = pos.y & 4;
|
||||
uint is_col13 = pos.y & 2;
|
||||
uint is_col12 = is_col23 ^ (is_col13 << 1);
|
||||
coord.x ^= is_col12; // If cols 1 or 2, flip bit 3 of x
|
||||
|
||||
if (any(floor(uniform.scale) != uniform.scale))
|
||||
coord = uint2(float2(coord) * uniform.scale);
|
||||
else
|
||||
coord = mul24(coord, uint2(uniform.scale));
|
||||
|
||||
float4 pixel = res.tex.read(coord);
|
||||
|
||||
uint4 denorm_c = (uint4)(pixel * 255.5f);
|
||||
if ((pos.y & 2u) == 0u)
|
||||
{
|
||||
uint red = (denorm_c.r >> 3) & 0x1Fu;
|
||||
uint green = (denorm_c.g >> 3) & 0x1Fu;
|
||||
float sel0 = (float)(((green << 5) | red) & 0xFF) / 255.0f;
|
||||
|
||||
return float4(sel0);
|
||||
}
|
||||
else
|
||||
{
|
||||
uint green = (denorm_c.g >> 3) & 0x1Fu;
|
||||
uint blue = (denorm_c.b >> 3) & 0x1Fu;
|
||||
uint alpha = denorm_c.a & 0x80u;
|
||||
float sel0 = (float)((alpha | (blue << 2) | (green >> 3)) & 0xFF) / 255.0f;
|
||||
|
||||
return float4(sel0);
|
||||
}
|
||||
}
|
||||
|
||||
fragment float4 ps_convert_rgba_8i(ConvertShaderData data [[stage_in]], DirectReadTextureIn<float> res,
|
||||
constant GSMTLIndexedConvertPSUniform& uniform [[buffer(GSMTLBufferIndexUniforms)]])
|
||||
{
|
||||
|
||||
@@ -350,10 +350,11 @@ bool GSDeviceOGL::Create(GSVSyncMode vsync_mode, bool allow_present_throttle)
|
||||
return false;
|
||||
m_convert.ps[i].SetFormattedName("Convert pipe %s", name);
|
||||
|
||||
if (static_cast<ShaderConvert>(i) == ShaderConvert::RGBA_TO_8I)
|
||||
if (static_cast<ShaderConvert>(i) == ShaderConvert::RGBA_TO_8I || static_cast<ShaderConvert>(i) == ShaderConvert::RGB5A1_TO_8I)
|
||||
{
|
||||
m_convert.ps[i].RegisterUniform("SBW");
|
||||
m_convert.ps[i].RegisterUniform("DBW");
|
||||
m_convert.ps[i].RegisterUniform("PSM");
|
||||
m_convert.ps[i].RegisterUniform("ScaleFactor");
|
||||
}
|
||||
else if (static_cast<ShaderConvert>(i) == ShaderConvert::YUV)
|
||||
@@ -1594,12 +1595,13 @@ void GSDeviceOGL::ConvertToIndexedTexture(GSTexture* sTex, float sScale, u32 off
|
||||
{
|
||||
CommitClear(sTex, false);
|
||||
|
||||
const ShaderConvert shader = ShaderConvert::RGBA_TO_8I;
|
||||
const ShaderConvert shader = ((SPSM & 0xE) == 0) ? ShaderConvert::RGBA_TO_8I : ShaderConvert::RGB5A1_TO_8I;
|
||||
GLProgram& prog = m_convert.ps[static_cast<int>(shader)];
|
||||
prog.Bind();
|
||||
prog.Uniform1ui(0, SBW);
|
||||
prog.Uniform1ui(1, DBW);
|
||||
prog.Uniform1f(2, sScale);
|
||||
prog.Uniform1ui(2, SPSM);
|
||||
prog.Uniform1f(3, sScale);
|
||||
|
||||
OMSetDepthStencilState(m_convert.dss);
|
||||
OMSetBlendState(false);
|
||||
|
||||
@@ -3158,15 +3158,16 @@ void GSDeviceVK::ConvertToIndexedTexture(
|
||||
{
|
||||
u32 SBW;
|
||||
u32 DBW;
|
||||
u32 pad1[2];
|
||||
u32 PSM;
|
||||
u32 pad1[1];
|
||||
float ScaleFactor;
|
||||
float pad2[3];
|
||||
};
|
||||
|
||||
const Uniforms uniforms = {SBW, DBW, {}, sScale, {}};
|
||||
const Uniforms uniforms = {SBW, DBW, SPSM, {}, sScale, {}};
|
||||
SetUtilityPushConstants(&uniforms, sizeof(uniforms));
|
||||
|
||||
const ShaderConvert shader = ShaderConvert::RGBA_TO_8I;
|
||||
const ShaderConvert shader = ((SPSM & 0xE) == 0) ? ShaderConvert::RGBA_TO_8I : ShaderConvert::RGB5A1_TO_8I;
|
||||
const GSVector4 dRect(0, 0, dTex->GetWidth(), dTex->GetHeight());
|
||||
DoStretchRect(static_cast<GSTextureVK*>(sTex), GSVector4::zero(), static_cast<GSTextureVK*>(dTex), dRect,
|
||||
m_convert[static_cast<int>(shader)], false, true);
|
||||
|
||||
@@ -3,4 +3,4 @@
|
||||
|
||||
/// Version number for GS and other shaders. Increment whenever any of the contents of the
|
||||
/// shaders change, to invalidate the cache.
|
||||
static constexpr u32 SHADER_CACHE_VERSION = 65;
|
||||
static constexpr u32 SHADER_CACHE_VERSION = 66;
|
||||
|
||||
Reference in New Issue
Block a user