Repository navigation
Conversation
Progress report (cecb540 → 95b1f00)📈 System libraries: 42.35% (+0.25%, +47 implemented functions) ✅ 47 implemented
|
jotitadev
left a comment
There was a problem hiding this comment.
A Linux run, since the description lists none.
Machine: NVIDIA GeForce RTX 3070, driver 595.99.02, Vulkan 1.4.329, Ubuntu 26.04 (kernel 7.0.0-38), i7-8700. GCC 15.2, Release, BUILD_TESTING=ON. Head e983d881f merged onto main 31cbb55d7, no conflicts. After reconfiguring for the new library, the build finishes with no warnings.
GPUs tested: NVIDIA GeForce RTX 3070 (595.99.02), Linux; llvmpipe (Mesa 26.0.3), Linux
guest_pigletandguest_precompiled_shaderspass 3/3 withANYPS5_GPU="NVIDIA GeForce RTX 3070", 3/3 withANYPS5_GPU=llvmpipe, and 3/3 withANYPS5_GPUunset (both ICDs installed). WithANYPS5_GPU=NoSuchGPU,guest_pigletis skipped withno Vulkan 1.1 graphics device matches ANYPS5_GPU=NoSuchGPU, so the selector filters on Linux as well. The 3070 exposesVK_EXT_depth_clip_control, so that path is the one taken here.- Fault check on this driver: with the Y flip taken out of the draw viewport in
Context.cpp(originviewport[1], positive height),guest_pigletfails on the RTX 3070 at the first frame's texel check (Piglet check failed at line 204). With the flip restored, it passes. ctest -R "^agc" -E "agc_display_buffer_dcc|agc_driver_flip|agc_driver_lds_atomics64" -j1 --timeout 60: 591/593 pass, the same result as unchangedmainon this machine.agc_driver_stencil_ref_exportis skipped (noVK_EXT_shader_stencil_export), andagc_driver_store_over_untrackedfails as it does onmain(#6385).
I did not run the OpenOrbis piglet sample itself.
Written with AI assistance (Claude Code). I ran the tests above on my machine.
|
Thank you for the thorough Linux run, @jotitadev: two GPUs, the AI-assisted: yes (Claude Code). 🤖 Generated with Claude Code |
javierUDP
left a comment
There was a problem hiding this comment.
Static review on macOS, head of this branch. I could not build or run any of it: these libraries need the full build, which does not configure on macOS, so everything below comes from reading the code and from the OpenOrbis piglet sample, not from execution.
eglCreateWindowSurface leaks its Vulkan objects on every error path.
Image and Buffer (include/Vulkan.hpp) are plain structs with no destructor; they are released explicitly, as DestroySurfaceNow does with DestroyImage, DestroyBuffer and vkDestroyFramebuffer. EglCreateWindowSurface creates the colour image, the readback buffer and the framebuffer, and only then reaches three statements that throw:
Check(device.vkCreateFramebuffer(...), "vkCreateFramebuffer")if (created->videoOut < 0) throw ... sceVideoOutOpen failedif (sceVideoOutRegisterBuffers2(...) < 0) throw ... failed
When one of them throws, std::unique_ptr<WindowSurface> deletes the object without touching the handles, so a VkImage, its VkDeviceMemory and VkImageView, the VkFramebuffer, and the readback VkBuffer with its memory are all lost.
A title that creates a second window surface while the first is alive reaches this: the second sceVideoOutOpen fails, and each retry leaks that set again. EGL allows more than one window surface, so this is not only a malformed-input path.
Releasing what was created before rethrowing, or giving Surface the destructor that DestroySurfaceNow currently open-codes, would close all three at once.
What I checked and found correct, in case it saves someone repeating it:
- The export surface matches the sample exactly: this PR exports 46 EGL and GLES symbols, and the
pigletsample of OpenOrbissamples-elf-llvm-18.zipimports exactly those 46, with nothing missing and nothing unused. I took the import list fromrelinker --registryon the sample. Describe()bounds its copy withmin(item.name.size(), bufferSize - 1)and writes the terminator inside the buffer, soglGetActiveAttribandglGetActiveUniformdo not overrun a caller buffer.lastErroristhread_local, as EGL requires, andobjectsMutexis held across thesurfacesandcontextsupdates ineglMakeCurrent.
I did not review Context.cpp's GLES state machine beyond the queries above, the glslang path in Program.cpp, or the two companion PRs.
Written with AI assistance. The import cross-check above was run on my own machine; nothing here was executed.
| Check(device.vkCreateFramebuffer(device.device, &framebuffer, nullptr, &surface.framebuffer), "vkCreateFramebuffer"); | ||
|
|
||
| created->videoOut = sceVideoOutOpen(UserServiceUserIdSystem, VideoOutBusTypeMain, 0, nullptr); | ||
| if (created->videoOut < 0) throw std::runtime_error("eglCreateWindowSurface: sceVideoOutOpen failed"); |
There was a problem hiding this comment.
This throw, the one below it and the Check on vkCreateFramebuffer all run after the colour image, the readback buffer and the framebuffer exist, and Image/Buffer have no destructor, so unwinding here drops those handles. A second window surface created while the first is open reaches it through sceVideoOutOpen.
|
Thanks, this builds and both guest tests pass for us on current main (NVIDIA, Linux). One change before merge, the same point javierUDP raised: in |
|
There are four more problems besides the 1.
A title that repeats Context::~Context() {
for (auto& [name, program] : programs) program->deletePending = true;
currentProgram = 0;
ReleasePrograms();
for (auto& image : retired) device.DestroyImage(image);
for (auto& [name, texture] : textures) device.DestroyImage(texture.image);
device.DestroyImage(incomplete.image);
for (auto& [key, sampler] : samplers) device.vkDestroySampler(device.device, sampler, nullptr);
for (const auto pool : pools) device.vkDestroyDescriptorPool(device.device, pool, nullptr);
for (auto* ring : {&vertexRing, &uniformRing})
for (auto& chunk : ring->chunks) device.DestroyBuffer(chunk);
device.vkFreeCommandBuffers(device.device, device.pool, 1, &commands);
}2. On current main, So suppose if (window->videoOut >= 0) {
VideoOutFlipStatus status{};
while (sceVideoOutGetFlipStatus(window->videoOut, &status) >= 0 && status.flipPendingNum != 0)
std::this_thread::sleep_for(std::chrono::milliseconds(1));
sceVideoOutClose(window->videoOut);
}3. A 1x1 texture with a mipmap minifying filter samples as incomplete, including with the default Example: create a white 1x1 4. Example: set |
…sample uses The OpenOrbis piglet sample loads libScePrecompiledShaders and looks up "texmap/v_2.vert" and "texmap/f_2.frag" in scePrecompiledShaderEntries, a table of 0x28-byte entries (name, size at 0x18, data at 0x20) that ends with a null name, and passes the data to glShaderBinary. The console table holds Sony's shader binaries, which AnyPS5 cannot ship. The library now exports the table with AnyPS5's own two shaders under those names, as GLSL ES 3.10 source behind an "APS5GLSL" line. They are written from the interface the sample uses: a_vertex with the position in xy and the texture coordinate in zw, the projection, model-view and texture-space matrices, the opacity applied to alpha and the sampler.
…glet sample The OpenOrbis piglet sample renders through libScePigletv2VSH, which AnyPS5 did not have. It imports scePigletSetConfigurationVSH, 13 EGL 1.4 functions and 33 OpenGL ES 2.0 functions, and passes the shaders it looks up in libScePrecompiledShaders to glShaderBinary. The library implements those 47 functions on Vulkan. The shaders are AnyPS5's GLSL ES source from libScePrecompiledShaders, compiled with glslang to SPIR-V; the loose uniforms are packed into one uniform buffer and the samplers are combined image samplers. Draws are recorded into one render pass per frame with pipelines cached by state, and eglSwapBuffers copies the frame into the next of two linear VideoOut buffers once no flip is pending and submits the flip. What the sample does not use throws. On MinGW, libc's import library is linked before glslang, and libstdc++ before the import library's trailing copy. The C++ runtime then binds to libc.prx, and glslang's std::string members, which the import library lists but libc.prx does not export, bind to libstdc++. guest_piglet renders five frames into an offscreen surface and checks their pixels: a 2x2 texture, alpha blending, a texture whose filter needs missing mipmaps, a viewport, and an RGB texture with 4-byte row alignment.
…x1 mipmapped textures and the minifying filter A window surface now releases its framebuffer, color image and readback buffer in its destructor, so eglCreateWindowSurface no longer leaks them when vkCreateFramebuffer, sceVideoOutOpen or sceVideoOutRegisterBuffers2 fails; it also waits for the last pending flip before closing the VideoOut port, so eglDestroySurface cannot free a display buffer the presenter is still reading. A context frees its command buffer, rings, descriptor pools, samplers, textures and programs when it is destroyed. A 1x1 texture is complete with a mipmap minifying filter, and samplers use maxLod 0.25 so GL_TEXTURE_MIN_FILTER applies when it differs from the magnifying filter (the Vulkan mapping of the OpenGL filter modes).
e983d88 to
95b1f00
Compare
|
Thanks @oneandonlydean, @nikowolf123 and @javierUDP. All five points are fixed in Get-fix/AnyPS5@95b1f0029, and the branch is rebased onto
AI-assisted: yes (Claude Code) 🤖 Generated with Claude Code |
… fallback pool in HostThreadLocal on Windows On MinGW the module compiles glslang's PoolAlloc.cpp itself, with DISABLE_THREAD_SUPPORT and its GetThreadPoolAllocator/SetThreadPoolAllocator renamed to unused internal functions, and defines both on a trivially destructible thread_local pointer plus a HostThreadLocal fallback pool. Its object defines every symbol of PoolAlloc.cpp.obj, so ld never takes that member from the shared libglslang.a, whose other members keep their thread support and init lock. prx_thread_local_destructors passes (373 modules), guest_piglet and guest_precompiled_shaders pass.
… when glslang's PoolAlloc.cpp changes or renames its pool accessors GlslangPoolAllocator.cpp compiles all of PoolAlloc.cpp with DISABLE_THREAD_SUPPORT, so a consistent rename of GetThreadPoolAllocator/SetThreadPoolAllocator or a new THREAD_LOCAL in that file would silently become process-wide. Configure now stops unless the newline-normalized SHA-256 of PoolAlloc.cpp matches the reviewed ba1640446f copy (re-checked on submodule bumps through CMAKE_CONFIGURE_DEPENDS), and -Werror=unused-function turns the never-defined Replaced* declarations into a compile error. The debt entry says so instead of claiming the test catches it. prx_thread_local_destructors, guest_piglet, host_thread_local and guest_precompiled_shaders pass.
…plements Remove the stub for NID M9RtXpjSYtE, which boykopovar#6521 implements, and correct the count in the debt entry.
|
should-fix 1. Freshness Envelope
2. Findings
3. Cross-PR Ledger
|
|
Exports with a name or library/NID already present in
|
|
Hi Thanks for the EGL/GLES 2 work. We ran this head (95b1f00) merged with current main on Linux and Windows, and two repo checks that landed on main since fail:
Please merge main and check with Thanks. |
What
The OpenOrbis piglet sample renders through the PS4 GLES library
libScePigletv2VSH, which AnyPS5 does not have. It imports 47 functions from it:scePigletSetConfigurationVSH, 13 EGL 1.4 functions and 33 OpenGL ES 2.0 functions. It loads the library andlibScePrecompiledShaderswithsceKernelLoadStartModuleand passes the shaders from #6520 toglShaderBinary.This adds
libScePigletv2VSHwith those 47 functions on Vulkan. The first commit is #6520; this pull request adds the second one.glShaderBinarytakes AnyPS5's GLSL ES source from feat(libScePrecompiledShaders): export the texmap shaders the piglet sample uses #6520;glLinkProgramcompiles it with glslang to SPIR-V, packs the loose uniforms into one uniform buffer and binds the samplers as combined image samplers. A PS4 shader binary throws.glPixelStoreiunpack alignment and theGL_RGBA,GL_RGB,GL_LUMINANCE,GL_LUMINANCE_ALPHAandGL_ALPHAtexel formats are handled. A texture whose minifying filter needs mipmaps it does not have samples as incomplete, as OpenGL ES requires. The Y axis is flipped with a negative viewport height, and OpenGL's clip-space depth is kept where the device hasVK_EXT_depth_clip_control.eglCreateWindowSurfaceopens a VideoOut port and registers two linear R8G8B8A8 buffers.eglSwapBufferscopies the frame into the next buffer once no flip is pending and submits the flip, on vblank for swap interval 1 and on hsync for 0. The sample callseglSwapIntervalbefore it has a context, so that call succeeds and sets the interval of the next surface.glGetErrorandeglGetErrorreport it. What the sample does not use throws, among it cube maps, mipmap levels other than 0, texel types other thanGL_UNSIGNED_BYTE, shared contexts andGL_LINE_LOOP;eglChooseConfigfinds no config with depth or stencil.__cxa_throw,_Unwind_*) then binds tolibc.prx, so exceptions thrown here reach the caller's handlers. glslang'sstd::stringmembers bind to libstdc++, because the import library lists 12 of them thatlibc.prxdoes not export, which made the library fail to load with error 127.The limits are in the new
docs/dev/debt/libScePigletv2VSH.md. Part of the PS4 homebrew work tracked in #3093.Tested
Windows 11 Pro 26200, WinLibs GCC 15.2.0 r7, Release,
BUILD_TESTING=ON, onmain03c4cb5e7:guest_piglettest creates a 64x64 offscreen surface, links the two shaders from the table and renders five frames, checking pixels in each: a 2x2 RGBA texture on the left half (the four texels in place and the clear colour elsewhere); the same with opacity 0.5 andGL_SRC_ALPHAblending; a mipmapping filter without mipmaps (black); a 32x32 viewport; an RGB texture with the default 4-byte row alignment. It also checks EGL initialization, config choice,eglSwapIntervalwithout a context, the reflected attribute and uniforms, the GL errors of invalid calls, and that a PS4 shader binary throws an exception the test catches.glViewport, writingglUniform1fat offset 0, accepting a PS4 binary as source,eglSwapIntervalfailing without a context.libScePigletv2VSH.prxexports exactly the 47 functions the sample imports, and imports fromlibc.prxonly functions the patchedlibc.prxexports.main03c4cb5e7with this, feat(libkernel): load system libraries from their console paths #6519, fix(relinker): search libc.prx for libkernel-only Windows executables #5990 to fix(relinker): stop module syscall scans at the PLT and skip the PS4 loader path #5994, feat(libSceFreeType): implement the six FreeType functions OpenOrbis samples use #6376, fix(relinker): accept section-relative guest module relocations #5138 and a change that answers the LinuxTIOCGWINSZwithENOTTY, as fix(libkernel): return ENOTTY for malformed ioctl requests #5569 did: it loads both modules, printsGL_RENDERER: AnyPS5 Piglet on Vulkan, finds both shaders and draws its rotating textured square at 59.96 FPS (window titleOpenOrbis piglet sample | FPS: 59.96 (666)). With neither library, it stops at start-up with 48FAIL: unresolved ELF importlines, one for each function and one forscePrecompiledShaderEntries. The 14 other samples that start with my open pull requests still start.main03c4cb5e7: 1296 of 1300 pass.agc_driver_gpu_indirect_arguments_misaligned_writer_aheaddoes not compile with MinGW onmain(test(agc): align the indirect arguments block at run time #6452 fixes it), andprx_thread_local_destructorsfails as it did onmain92cdc7b62on this machine without my changes;agc_shader_disk_cache(timeout) andagc_driver_multisample_fill_host_onlyfailed underctest -j8and pass when run alone. Full ctest of the build with all my open pull requests: 1304 of 1306 pass; the two that do not are the first two above.tools/check_conventions.pypasses.Not tested on Linux or macOS.
Checklist
main; no other open PR implements the same functionsNotImplemented_nid_no_patch); silent stubs are listed under Silent stubs in their library's technical debt file.mdfiles or images added to the repository (attach them to this PR)🤖 Generated with Claude Code