Return the raw texel bits: dmask bit i selects texel dword i, dwords past the
texel read 0 and the _sgn forms sign-extend texels narrower than 32 bits
(measured on RDNA2 hardware). Only formats whose bits are exactly recoverable
from the sampled view are accepted (unsigned/signed integer, unorm up to 16
bits, 32-bit float components), on a direct sampled image with identity
swizzle; anything else throws.
Co-Authored-By: Claude <noreply@anthropic.com>
Four more libSceHttp exports, following the library's existing "no network emulated" model:
- sceHttpCreateRequest2 -> a new handle, like sceHttpCreateRequestWithURL2
- sceHttpsEnableOption -> 0, the counterpart of the existing sceHttpsDisableOption
- sceHttpsLoadCert -> 0 (certificates are accepted and ignored; no TLS is performed)
- sceHttpGetLastErrno -> 0 (no request reaches the network, so no errno is recorded); a
null output pointer returns ERROR_INVALID_VALUE, like the other getters in this file
Signatures follow the public OpenOrbis SDK headers. GuestHttp is extended to cover the four
functions; the new assertions fail without the change (the symbols are undefined).
Two exports were missing. System modules are linked statically, so load and unload are
reference counts over the known module table, exactly like the existing
sceSysmoduleLoadModuleInternalWithArg and sceSysmoduleUnloadModule:
- sceSysmoduleLoadModuleInternal(uint32_t) -> increments the module's load count, returns 0
- sceSysmoduleUnloadModuleInternal(uint32_t) -> decrements it, or 0x80A90003 when the module
was not loaded
Unknown or zero ids throw, like the sibling internal loader. Adds a CMakeLists.txt so the
library can carry its guest test. Signatures follow the public OpenOrbis SDK headers.
New test core/libs/tests/GuestSysmodule.cpp loads a module twice, unloads it twice and checks
the not-loaded error on a third unload; it fails without the change (the symbols are
undefined) and passes with it.
Format loads divided by 2^b-1 with OpFDiv, which Vulkan only bounds to 2.5 ULP; RADV returns a
different f32 than the hardware for many 8- and 16-bit values. The quotient is now built on the
bits: v/(2^b-1) is v's b bits repeated, so the mantissa is the rotated value replicated and rounded
on the next bit (no ties). Adds an execution test of buffer_load_format_x..xyzw,
tbuffer_load_format_x/xy/xyz and buffer_store_format_x..xyzw against values measured on RDNA.
Co-Authored-By: Claude <noreply@anthropic.com>
nanosleep and _nanosleep forwarded the result of sceKernelNanosleep, which
returned -1 for a rejected request: errno was never set, and the sce call
returned a value that is not an sce error. A request with negative seconds
was rejected as well, where FreeBSD's kern_nanosleep returns 0 without
sleeping.
nanosleep and _nanosleep now return -1 with errno set to EINVAL when tv_nsec
is outside [0, 1000000000) and to EFAULT for a null request;
sceKernelNanosleep returns the matching SCE_KERNEL_ERROR code. A request
with valid nanoseconds and negative seconds returns 0 at once.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
sceAgcAcbDmaData emits the 7-dword DMA_DATA packet through
Agc::Command::WriteDma, the writer sceAgcDcbDmaData shares, so its size
query returns the same 28 bytes instead of throwing.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
sceAmprCommandBufferPushMarker, PushMarkerWithColor, PopMarker, SetMarker
and SetMarkerWithColor record a marker command, and the matching
sceAmprMeasureCommandSize functions return its size. The APR executor
skips markers, as it does a nop.
Signatures follow the ampr_emu reimplementation of libSceAmpr.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Report the horizontal and vertical resolution kept in the font handle's
style block, as set when the font is opened (72 dpi) or by
sceFontSetResolutionDpi. Error handling follows the other handle getters:
an invalid handle or two null outputs fail and clear the outputs.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The mix level is a linear gain on the pad speaker port, 32768 being 0 dB.
A pad speaker port opens at 11626 (-9 dB). An unknown handle, a port of
another type and a level above 0 dB return the AudioOut error codes; a
negative level throws, as its effect is unknown.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
sceAgcBranchPatchSetCompareAddress, sceAgcBranchPatchSetThenTarget and
sceAgcBranchPatchSetElseTarget rewrite the compare address and the two
buffer targets of the packet sceAgcCbBranch emits. The then target is
the first buffer and the else target the second, as in AMD's
COND_INDIRECT_BUFFER packet. The cache policy bits are kept.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The POSIX layer only exported init, destroy, rdlock, wrlock and unlock.
pthread_rwlock_tryrdlock, pthread_rwlock_trywrlock,
pthread_rwlock_timedrdlock and pthread_rwlock_timedwrlock now wrap the
existing scePthreadRwlock functions and accept the static initializer.
The timed variants take an absolute CLOCK_REALTIME deadline. Like
FreeBSD libthr they try the lock first and only validate abstime when
the lock is not free. A null abstime throws, as pthread_mutex_timedlock
does.
scePthreadRwlockTryrdlock and scePthreadRwlockTrywrlock return EBUSY
when the caller already holds the write lock instead of calling into
std::shared_timed_mutex, where that is undefined behaviour.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The decoder maps SOPK opcodes 0x17 to 0x1a to SWaitcnt, but no test encoded them and tools/progress.py only counted S_WAITCNT_VSCNT. The test runs the four waits with a null and a live register field and checks that SCC and the register are left unchanged.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Decode FLAT opcode 0x16 in the global segment and load one dword per
active lane from the SGPR pair base plus the signed offset plus four
times the lane id.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The decoder stopped at an s_endpgm unless the next word was a known branch
target. When an earlier branch jumps further than that word, the block right
after the s_endpgm is entered only from later code, so the program was cut
short and the graph builder rejected the branch as targeting an invalid
program counter. Stop only when no decoded branch targets a word at or past
the one after the s_endpgm.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
v_add_co_u32, v_sub_co_u32 and v_subrev_co_u32 (VOP3 0x30f, 0x310, 0x319)
decode to VAddI32, VSubI32 and VSubrevI32 and had no execution test.
tools/progress.py listed the first and the last as variants of those
opcodes but not v_sub_co_u32, which it reported as missing.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
On LDS the counter is at the instruction offset. The emitter added
M0[31:16] to it and required the offset to be below M0[15:0], which is
the GDS base and a size no other LDS access reads. The GDS path is
unchanged.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
VOP2 0x2b, 0x2c and 0x2d decode to the opcodes of v_mac_f32, v_madmk_f32
and v_madak_f32 and differ only by the encoding, which keeps them fused.
The progress map derives names from the opcode enum, so it listed the three
fused forms as missing.
The new test decodes the six encodings and checks that the translation
rounds the product separately for 0x1f-0x21, keeps 0x2b-0x2d fused, and
reads the accumulator and the literal from the right operand.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
OpConstantTrue and OpConstantFalse carry no operand word, so they reached the
declaration cache through the variadic Constant template, which builds the key
vector, and paid an allocation on every call. ConstantBool emits both, so a
shader paid it twice per boolean constant. Add the two-word overload; the
compile-shaped benchmark drops from 10413 allocations to 415.
Add agc_spirv_module_tests covering the interning contract: a repeated
declaration returns one id and is emitted once, operand shapes that share a
leading key word stay distinct, integral and enum operands agree, decorated
types stay separate from plain ones, memoized ids survive AllocateId, modules
do not share ids, and ids stay unique and contiguous past the cache capacity.
The test passes against both the previous header and this one, so it pins the
contract rather than the implementation.
Benchmark, pre-optimization header against this one, best of five:
hot loop x 2M 613.6 ms -> 46.3 ms 13.2x
compile-shaped 5000 instr 4.2 ms -> 0.4 ms 10.8x
64 compile-shaped modules 286.0 ms -> 25.4 ms 11.3x
Allocations for the compile-shaped case fall from 55217 to 415. Both builds
compute the same value over the same call sequence.
Co-Authored-By: Claude <noreply@anthropic.com>
Every SpirvModule::Type and Constant call built a heap std::vector key and
looked it up in a std::map keyed on std::vector, so the comparison walked the
key bytes. At the one to three such calls per emitted instruction a shader
issues thousands of them per compile.
Add a fixed-size, linearly probed declaration cache that holds the key inline
and is consulted before the key vector is built, making a repeated declaration
a hash and a compare. The cacheable shapes are those whose operands are a
word: OpTypeVoid, OpTypeBool, OpTypeInt, OpTypeFloat, OpTypeVector,
OpTypePointer, OpTypeStruct, OpTypeArray, OpTypeFunction and the scalar
OpConstant family. The overloads are constrained on word-sized operands so
that enum operands such as spv::StorageClassFunction reach the cache instead of
binding the variadic template by reference.
Measured with a harness driving the module through the emitters' call shapes:
80000 hot type and constant calls drop from 80074 heap allocations to 140. The
assigned ids and the emitted SPIR-V word stream are byte-identical.
Co-Authored-By: Claude <noreply@anthropic.com>
The PS5 libthr (FreeBSD) creates error-checking mutexes by default and has
PTHREAD_MUTEX_ADAPTIVE_NP (type 4); relocking an error-checking or adaptive
mutex returns EDEADLK. Default mutexes were Normal and type 4 was mapped to
Normal, so a relock threw instead of returning EDEADLK, which aborted an
Unreal Engine title's recursive directory scan.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The unsupported-instruction error now lists the instruction bytes, and the relink failure names the input file, the main executable or the guest module, on an extra Input: line.