mirror of
https://github.com/mihawk-99/PS5_RetroArch.git
synced 2026-10-18 23:09:29 -05:00
Correct RGUI RGBA4444 upload channel order and range
Verification: bash tools/verify.sh (all five gates, 25 tests); bash tools/run-title.sh --no-build --watch 30. Evidence: evidence/vulkan-menu-rgba/. Exhaustive 65536-value host check and zero-refusal console run; owner sees green RGUI but flicker remains unresolved.
This commit is contained in:
1 parent
574974ee2e
commit
5fb5d1a8c1
9 files changed
+171
-20
No files matched your search
+20
-19
@@ -35,30 +35,31 @@ frontend. Previously only the CPU video driver's open method called it.
|
||||
|
||||
## Current diagnosis
|
||||
|
||||
The RGBA conversion is corrected and exhaustively tested over all 65,536 inputs,
|
||||
but the owner still reports wrong colours. The 30-second colour run completed
|
||||
and the script closed it, with zero refusals/errors in the retrieved trace.
|
||||
A subsequent identity build proves the console runs the intended input set:
|
||||
The owner now clarifies that the menu is green, with blue flickers everywhere and
|
||||
black triangles appearing/disappearing in fixed positions. The RGBA4444 conversion
|
||||
correction is exhaustive over all 65,536 inputs. The 30-second colour run completed
|
||||
and the script closed it, with zero refusals or recorded API errors. Evidence:
|
||||
`evidence/vulkan-menu-rgba/`. Flicker remains unresolved.
|
||||
|
||||
The identity build proves the console runs the intended input set:
|
||||
`df3a593a85388d58bc9fcc847dbd1deac6d9f1de8e4170493e84a84f87e362e3`.
|
||||
`evidence/vulkan-build-identity/` records local/remote/trace agreement. All five
|
||||
gates and 25 tests pass. Generic startup markers alone cannot prove a build.
|
||||
gates and 25 tests passed. Generic startup markers alone cannot prove a build.
|
||||
|
||||
The next diagnostic is to read the uploaded texture and rendered image through
|
||||
the released driver's test-only image-storage API, without hardware writes or
|
||||
sibling changes, to separate upload pixels from rendered pixels.
|
||||
Read-only driver inspection found a relevant historical blue-channel corruption:
|
||||
`../PS5_Vulkan/docs/HARDWARE_FINDINGS.md` records source-alpha blending needing
|
||||
FP16_ABGR pixel exports. The current driver chooses that for blend-enabled
|
||||
pipelines, while opaque pipelines use 32_ABGR and omit explicit blend registers.
|
||||
This is a hypothesis for mixed opaque/blended draws, not a proven root cause.
|
||||
|
||||
## Next smallest step
|
||||
|
||||
Correct the colour conversion using the RGUI producer's actual RGBA4444 nibble
|
||||
order (R in bits 12-15) and expand each nibble to 8 bits. The current 0028 code
|
||||
reverses red/blue and scales 15 to 240 instead of 255. Preserve A2's matching
|
||||
32-bit RGBA textures and plain-copy path. Diagnose flicker separately from colour.
|
||||
|
||||
A host regression test also caught the existing 0023 patch marker missing from
|
||||
its own replacement. The marker-only fix is verified separately: all five gates and 22 host tests
|
||||
pass. Evidence is in `evidence/frontend-patch-idempotence/`. A fresh upstream replay is byte-identical on its second application.
|
||||
The configured shader source was regenerated from upstream plus the named edits
|
||||
to remove the accumulated duplicates. No colour or rendering code was changed.
|
||||
Test a frontend-only, equivalent ONE/ZERO blend state for the opaque stock shader
|
||||
pass, to force explicit blend programming and FP16 exports. Compare the same menu
|
||||
on the same unchanged driver; keep source-alpha menu blending unchanged. If that
|
||||
does not resolve the defect, retire the diagnostic and report the remaining
|
||||
uncertainty rather than claiming a driver fix. Public debug image readback is
|
||||
another possible way to separate correct upload pixels from corrupt rendering.
|
||||
|
||||
## Working notes
|
||||
|
||||
@@ -74,7 +75,7 @@ to remove the accumulated duplicates. No colour or rendering code was changed.
|
||||
- A2 remains the matching 32-bit RGBA upload and plain copy path; do not reopen
|
||||
the settled choice. The traced menu dynamic/staging formats are both 37.
|
||||
- CPU fallback sources and registration have not been changed.
|
||||
- Patch count is 68 with the pending RGBA conversion correction. `vendor/` is untouched.
|
||||
- Patch count is 68 including the RGBA conversion correction. `vendor/` is untouched.
|
||||
- Fresh replay of all port patches succeeds. The configured shader file contains
|
||||
only the intended 0023 sampler fallback block after regeneration. Its marker
|
||||
now appears in its replacement, so repeated builds cannot accumulate it.
|
||||
|
||||
@@ -2481,3 +2481,14 @@ Patch 0028 instead writes the blue nibble into the R8G8B8A8 texture's red byte a
|
||||
red into blue, and shifts four-bit channels into only the high nibble of each
|
||||
byte (15 becomes 240). This is a frontend conversion defect, independently of
|
||||
the still-unexplained flicker; fixing it preserves matching 32-bit upload formats.
|
||||
|
||||
## 2026-09-19 — RGUI upload and remaining visual corruption
|
||||
|
||||
The RGUI producer packs R in bits 12-15, G in 8-11, B in 4-7 and A in 0-3.
|
||||
Patch 0028 reversed R/B and expanded to 240 rather than 255; 0055 corrects both.
|
||||
The exhaustive producer-to-upload test covers all 65,536 words. Evidence is in
|
||||
`evidence/vulkan-menu-rgba/`; the owner sees green RGUI but blue flicker and fixed
|
||||
black triangles remain. Successful Vulkan calls alone do not prove correct pixels.
|
||||
Read-only driver findings record an earlier similar blue blending defect fixed by
|
||||
FP16 exports; current code skips blend-register writes on opaque draws. This
|
||||
suggests a mixed-pipeline diagnostic, not a confirmed cause of this title's issue.
|
||||
@@ -1601,3 +1601,15 @@ reported exactly the staged identity in its trace; see
|
||||
but does not prove correct pixels. The identity run closed before its final query.
|
||||
No driver project files were modified and no new dependency or compiler flag was
|
||||
introduced. The generated header is not committed.
|
||||
|
||||
## 2026-09-19 — Correct the RGUI upload channel order and range
|
||||
|
||||
Patch 0055 expands the producer's RGBA4444 nibbles to RGBA8888 bytes, preserving
|
||||
A2's matching 32-bit textures and plain-copy route. Its regression test failed
|
||||
before the fix and checks all 65,536 inputs after it. The five gates passed with
|
||||
25 tests. The full 30-second colour run ended with a live title which the script
|
||||
closed; its fresh trace has zero refusals and successful initial API results.
|
||||
`evidence/vulkan-menu-rgba/` records the capture and expectations. The subsequent
|
||||
identity run was verified as the intended input set. The owner's clarified report
|
||||
is a green menu with blue flicker and black triangles; upload correction does not
|
||||
resolve GPU corruption, and the overall goal remains open.
|
||||
@@ -0,0 +1,30 @@
|
||||
{
|
||||
"step": "vulkan-menu-rgba",
|
||||
"command": "bash tools/verify.sh; bash tools/run-title.sh --no-build --watch 30",
|
||||
"revision": "44c6fb7 plus RGBA correction (also tested before identity instrumentation)",
|
||||
"raw_capture": "klog/gpu-colour-latest-trace.txt",
|
||||
"raw_lines": 385,
|
||||
"lines": [
|
||||
"gpu result: vkEndCommandBuffer calls=1 failures=0 result=0",
|
||||
"gpu result: vkQueueSubmit calls=1 failures=0 result=0",
|
||||
"gpu result: vkEndCommandBuffer calls=2 failures=0 result=0",
|
||||
"gpu result: vkQueueSubmit calls=2 failures=0 result=0",
|
||||
"gpu result: vkEndCommandBuffer calls=3 failures=0 result=0",
|
||||
"gpu result: vkQueueSubmit calls=3 failures=0 result=0",
|
||||
"gpu result: vkEndCommandBuffer calls=4 failures=0 result=0",
|
||||
"gpu result: vkQueueSubmit calls=4 failures=0 result=0",
|
||||
"gpu result: vkQueuePresentKHR calls=1 failures=0 result=0",
|
||||
"gpu result: swapchain image calls=1 failures=0 result=0",
|
||||
"vulkan copy_staging_to_dynamic: dynamic 320x240 fmt=37 type=2, staging fmt=37 type=1, compute=0",
|
||||
"gpu result: vkQueuePresentKHR calls=2 failures=0 result=0",
|
||||
"gpu result: swapchain image calls=2 failures=0 result=0",
|
||||
"gpu result: vkQueuePresentKHR calls=3 failures=0 result=0",
|
||||
"gpu result: swapchain image calls=3 failures=0 result=0",
|
||||
"gpu result: vkQueuePresentKHR calls=4 failures=0 result=0",
|
||||
"gpu result: swapchain image calls=4 failures=0 result=0",
|
||||
"audit: refusals=0; recorded API failures=0",
|
||||
"runner: completed 30-second watch, final process count=1, script closed title",
|
||||
"host: all 65536 RGBA4444 inputs match producer and RGBA8888 bytes",
|
||||
"owner: green RGUI visible, blue flickers and fixed-position black triangles remain"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"step": "vulkan-menu-rgba",
|
||||
"note": "Corrects upload channel order/range only; GPU flicker remains unresolved.",
|
||||
"must_contain": [
|
||||
"host: all 65536",
|
||||
"refusals=0",
|
||||
"vkEndCommandBuffer calls=4 failures=0 result=0",
|
||||
"green RGUI visible"
|
||||
],
|
||||
"must_not_contain": []
|
||||
}
|
||||
@@ -31,3 +31,6 @@
|
||||
|
||||
# 0054 observe command completion, queue submission, presentation and menu draw inputs
|
||||
0054-observe-vulkan-api-results
|
||||
|
||||
# 0055 convert the RGUI producer RGBA4444 channels to full-range RGBA8888
|
||||
0055-correct-rgui-rgba8888-upload
|
||||
@@ -300,7 +300,7 @@ class PortPatches(unittest.TestCase):
|
||||
change deliberately, in a commit that says why.
|
||||
"""
|
||||
self.assertEqual(
|
||||
len(self.blocks()), 67,
|
||||
len(self.blocks()), 68,
|
||||
"the patch count changed: if a block was added or removed on purpose, "
|
||||
"update this number in the same commit and say why in its message")
|
||||
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
"""RGUI's producer and the port's upload must agree on RGBA channel order."""
|
||||
|
||||
import ast
|
||||
import re
|
||||
import shutil
|
||||
import subprocess
|
||||
import tempfile
|
||||
import unittest
|
||||
from pathlib import Path
|
||||
|
||||
ROOT = Path(__file__).resolve().parent.parent
|
||||
|
||||
|
||||
class VulkanMenuColor(unittest.TestCase):
|
||||
def test_all_rgba4444_values_reach_the_matching_rgba8888_bytes(self):
|
||||
script = ast.parse((ROOT / "tools/apply-port-patches.py").read_text())
|
||||
edits = next(ast.literal_eval(node.value) for node in script.body
|
||||
if isinstance(node, ast.Assign)
|
||||
and getattr(node.targets[0], "id", "") == "EDITS")
|
||||
source = (ROOT / "vendor/retroarch/gfx/drivers/vulkan.c").read_text()
|
||||
for name, anchor, replacement, marker in edits:
|
||||
if name == "gfx/drivers/vulkan.c" and marker not in source:
|
||||
self.assertIn(anchor, source)
|
||||
source = source.replace(anchor, replacement, 1)
|
||||
upload = source.split("static void vulkan_set_texture_frame(", 1)[1]
|
||||
expression = re.search(r"\n\s+\*dstpix\s*=\s*(.*?);", upload, re.S).group(1)
|
||||
rgui = (ROOT / "vendor/retroarch/menu/drivers/rgui.c").read_text()
|
||||
producer = re.search(r"static uint16_t argb32_to_rgba4444\(uint32_t col\)\s*"
|
||||
r"\{(.*?)\n\}", rgui, re.S).group(1)
|
||||
program = r'''
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
static uint16_t produce(uint32_t col) { PRODUCER }
|
||||
static uint32_t convert(uint32_t pix) { return EXPRESSION; }
|
||||
int main(void)
|
||||
{
|
||||
for (unsigned rgba = 0; rgba < 65536; ++rgba)
|
||||
{
|
||||
unsigned r = ((rgba >> 12) & 15) * 17;
|
||||
unsigned g = ((rgba >> 8) & 15) * 17;
|
||||
unsigned b = ((rgba >> 4) & 15) * 17;
|
||||
unsigned a = (rgba & 15) * 17;
|
||||
uint16_t packed = produce((a << 24) | (r << 16) | (g << 8) | b);
|
||||
uint32_t got = convert(packed);
|
||||
uint32_t want = r | (g << 8) | (b << 16) | (a << 24);
|
||||
if (got != want)
|
||||
{
|
||||
fprintf(stderr, "RGBA4444=%04x got=%08x want=%08x\n", packed, got, want);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
puts("65536 RGBA4444 colours match RGBA8888 byte order and full-range expansion");
|
||||
}
|
||||
'''.replace("PRODUCER", producer).replace("EXPRESSION", expression)
|
||||
compiler = shutil.which("clang") or shutil.which("gcc")
|
||||
self.assertIsNotNone(compiler)
|
||||
with tempfile.TemporaryDirectory() as directory:
|
||||
source_file = Path(directory) / "colour.c"
|
||||
binary = Path(directory) / "colour"
|
||||
source_file.write_text(program)
|
||||
subprocess.run([compiler, "-std=c11", str(source_file), "-o", str(binary)],
|
||||
check=True, capture_output=True, text=True)
|
||||
run = subprocess.run([str(binary)], capture_output=True, text=True)
|
||||
self.assertEqual(run.returncode, 0, run.stderr)
|
||||
@@ -1939,6 +1939,25 @@ EDITS = [
|
||||
" vkCmdDraw(vk->cmd, 6, 1, 0, 0);\n",
|
||||
"gpu quad: alpha=",
|
||||
),
|
||||
(
|
||||
"gfx/drivers/vulkan.c",
|
||||
" /* Added by this port (patches/series, 0028): R8G8B8A8's byte order,\n"
|
||||
" * from the B4G4R4A4 source the caller hands over. */\n"
|
||||
" *dstpix = (\n"
|
||||
" (pix & 0x00f0) )\n"
|
||||
" | ((pix & 0x0f00) << 4)\n"
|
||||
" | ((pix & 0xf000) << 8)\n"
|
||||
" | ((pix & 0x000f) << 28);\n",
|
||||
" /* Supersedes patches/series, 0028. */\n"
|
||||
" /* Added by this port (patches/series, 0055): RGUI produces RGBA4444,\n"
|
||||
" * red in the high nibble. Expand all channels to 0..255 and store\n"
|
||||
" * R,G,B,A bytes for the matching R8G8B8A8 staging/dynamic textures. */\n"
|
||||
" *dstpix = (((pix >> 12) & 15u)\n"
|
||||
" | (((pix >> 8) & 15u) << 8)\n"
|
||||
" | (((pix >> 4) & 15u) << 16)\n"
|
||||
" | ((pix & 15u) << 24)) * 17u;\n",
|
||||
"patches/series, 0055",
|
||||
),
|
||||
]
|
||||
|
||||
|
||||
|
||||
Reference in new issue
Block a user