Skip to content

feat(shader): implement s_bcnt0_i32_b64, s_ff0_i32_b64, s_flbit_i32(_i64), s_quadmask_b32 - #255

Merged
boykopovar merged 2 commits into
boykopovar:mainfrom
adriadam10:feat/scalar-bit-count-ops
Oct 2, 2026
Merged

boykopovar merged 2 commits into
boykopovar:mainfrom
adriadam10:feat/scalar-bit-count-ops

Conversation

@adriadam10

Copy link
Copy Markdown
Collaborator

What

The decoder threw "unsupported SOP1 opcode" for:

  • s_bcnt0_i32_b64 (0x0e): zeros in a 64-bit value; SCC = result != 0
  • s_ff0_i32_b64 (0x12): first zero bit of a 64-bit value, -1 if none
  • s_flbit_i32 (0x17): leading bits equal to the sign bit, -1 for 0 and -1 (same as v_ffbh_i32, reuses vFfbh32(inst, true))
  • s_flbit_i32_i64 (0x18): the 64-bit signed form
  • s_quadmask_b32 (0x2c): the 32-bit form of s_quadmask_b64; SCC = result != 0

The 64-bit find/flbit helpers take a flag (sFfI32B64(inst, zero), sFlbitI32B64(inst, sign)) and sQuadmaskB64 became sQuadmask(inst, wide); the existing opcodes call them with the old behaviour.

Found with an ISA sweep (every gfx1013 opcode from llvm-mc through DecodeRdnaInstruction + TranslateInstruction).

Test agc_driver_scalar_bit_count: hand-assembled wave32 shader with a scalar loop over the 32 lanes: v_readlane each lane's 64-bit input into SGPRs, run the five ops (plus s_cselect to capture SCC after s_bcnt0 and s_quadmask), v_writelane the results back. Inputs are edge values (0, -1, half-ones, single bits, sign patterns) and pseudo-random ones, checked against a C++ model (std::popcount, countr_one, countl_zero).

Writing this test is how #254 was found: v_writelane wrote every lane. Like that test, it is skipped when the subgroup is smaller than a wave32 (lavapipe: 8).

Tested

Linux, RADV (Radeon 660M): passes; without the change it fails with "unsupported SOP1 opcode 14". lavapipe: skipped (subgroup 8).

Merge note: RdnaScalarOpDecoder.cpp has a one-line adjacent conflict with #220 (0x2c here, 0x29-0x2b there), keep both.

Checklist

@github-actions

github-actions Bot commented Oct 1, 2026 •

Copy link
Copy Markdown

Progress report (01eaae0 → f3f9b4f)

📈 GPU shader instructions: 55.06% (+0.43%, +5 implemented instructions)

✅ 5 implemented
Encoding Name
SOP1 S_BCNT0_I32_B64
SOP1 S_FF0_I32_B64
SOP1 S_FLBIT_I32
SOP1 S_FLBIT_I32_I64
SOP1 S_QUADMASK_B32

@github-actions github-actions Bot added build shader core/shader agc libSceAgc* ci .github labels Oct 1, 2026
@adriadam10
adriadam10 force-pushed the feat/scalar-bit-count-ops branch from ed2e11a to 32b8c81 Compare October 1, 2026 20:51
@adriadam10
adriadam10 force-pushed the feat/scalar-bit-count-ops branch from 32b8c81 to f8df2a7 Compare October 2, 2026 04:19
adriadam10 and others added 2 commits October 2, 2026 09:59
The WriteLane IR takes {value, lane, previous}, as the translation and the
read-lane eliminator use it, but the SPIR-V emitter compared the lane id with
the previous value and selected between the lane index and the value. Every
v_writelane therefore wrote its value to all lanes (or the lane index to the
lane whose old value happened to equal its id).

Co-Authored-By: Claude <noreply@anthropic.com>
…i64), s_quadmask_b32

The decoder threw for these SOP1 opcodes. The 64-bit find-first-zero and
signed leading-bit counts reuse the existing 64-bit helpers with a flag;
s_quadmask_b32 is the 32-bit half of s_quadmask_b64. s_bcnt0 and s_quadmask
set SCC to result != 0; the find and leading-bit forms leave it.

Co-Authored-By: Claude <noreply@anthropic.com>
@adriadam10
adriadam10 force-pushed the feat/scalar-bit-count-ops branch from f8df2a7 to f3f9b4f Compare October 2, 2026 08:05
@github-actions github-actions Bot removed the needs rebase Conflicts with main, rebase needed label Oct 2, 2026
@github-actions

github-actions Bot commented Oct 2, 2026 •

Copy link
Copy Markdown

Other open pull requests touch the same code. Merging one will break the other, or both implement the same thing. If this one builds on them, list them in Depends on.

Pull request Conflicting files (lines on main) Same exports Same new files
#387 core/shader/recompiler/RdnaDecoder/include/RdnaDecoder/RdnaOpcode.hpp L158-160
core/shader/recompiler/RdnaDecoder/src/RdnaOpcode.cpp L55-57
core/shader/recompiler/RdnaDecoder/src/RdnaScalarOpDecoder.cpp L29, L45
core/shader/recompiler/Translation/include/Translation/TranslationContext.hpp L184
core/shader/recompiler/Translation/src/ScalarInstructions.cpp L309, L323

@boykopovar
boykopovar merged commit 2af9dda into boykopovar:main Oct 2, 2026
3 checks passed
@adriadam10
adriadam10 deleted the feat/scalar-bit-count-ops branch October 3, 2026 05:08
oneandonlydean added a commit to oneandonlydean/AnyPS5 that referenced this pull request Oct 3, 2026
…oykopovar#304 boykopovar#305 boykopovar#306 boykopovar#322 boykopovar#409 boykopovar#416, boykopovar#276 boykopovar#277 boykopovar#275 boykopovar#307, shader ops boykopovar#226 boykopovar#255 boykopovar#260 boykopovar#280 boykopovar#308 boykopovar#309 boykopovar#311 boykopovar#318 boykopovar#320 boykopovar#324 boykopovar#326 boykopovar#379 boykopovar#384 boykopovar#399, boykopovar#261, kernel boykopovar#335 boykopovar#341 boykopovar#349 boykopovar#355, libs boykopovar#227 boykopovar#244 boykopovar#245 boykopovar#273 boykopovar#274 boykopovar#279 boykopovar#286 boykopovar#287 boykopovar#289 boykopovar#296 boykopovar#300 boykopovar#328 boykopovar#358 boykopovar#402) into astrobot

Where our PR merged in a revised form, main's version is taken; where
astrobot carries the same work plus later local commits, astrobot's code
stays and main's additions appear once.

Conflicts:
- AvPlayer (Export.cpp both libs, include/AvPlayer.hpp, src/Player.cpp,
  src/Source.cpp, AvPlayerLibrary.cmake, CMakeLists.txt, SceTypes.hpp,
  tests/GuestAvPlayer.cpp): main's boykopovar#307 (our reviewed squash, which carries
  9c8e7fd e9ea5c8 adcede3 fb4eeb9 953057c ac456ee). It links the
  shared ffmpeg-core target, so astrobot's second FFmpeg build goes:
  3rdparty/FFmpeg submodule, core/libs/FFmpeg.cmake and src/Exports.cpp.
- libScePngEnc: main's boykopovar#227 (supersedes OverkillLabs' encoder).
- libScePad Export.cpp: main's boykopovar#287 tilt correction (supersedes 49d45f5).
- libSceAudioPropagation Export.cpp: astrobot's object model, which
  defines every function boykopovar#289 declares as a stub.
- libSceSaveData.native Export.cpp: both (SaveDataHoldWrites and boykopovar#289's
  unknown exports).
- VideoOutDriver.cpp: astrobot's (2546bd1 counters around boykopovar#416's
  lastFlipVblank store, same value). tests/Flip.cpp: boykopovar#416's pacing test and
  boykopovar#417's after-GPU test both kept.
- boykopovar#278 files (DisplayFormat, VulkanDevice, GpuColorTransfer,
  ResidentPresent, agc CMakeLists): main's comment-free boykopovar#278 plus
  astrobot's P5 present-direct (b29728d), which removed DetileImage,
  ResidentPresent.hpp and the recorder-test hook; the resident present test
  stays its own executable.
- VulkanDevice.cpp/.hpp: astrobot's GDS, local memory probe, sample dumps
  and P5 code; boykopovar#303/boykopovar#409 comments as main has them; main's shader clock
  (boykopovar#324) and DepthSurface-free includes.
- RequestSerializer.cpp: version stays 8 (6 mesh passthrough, 7
  nonConstantImageOffsets, 8 astrobot's later field). boykopovar#303's auto-merged
  second write and read of nonConstantImageOffsets removed.
- SpirvEmitter.hpp, SpirvEmitterState.hpp, Recompiler.hpp/.cpp, StageIO.hpp,
  SpirvOptimizer.cpp, InstructionTranslator.cpp, ShaderReplay.cpp: local
  fields kept, boykopovar#303/boykopovar#305 comments as main has them.
- SpirvAluEmitterMath.cpp: v_readlane keeps the split-wave path and takes
  boykopovar#322's wrap at the wave size for the others.
- SpirvEmitter.cpp: astrobot's single-lane layout check.
- SpirvFlowEmitter.cpp: boykopovar#304 as merged (the second lane emits a shared
  value itself when the first lane defined nothing).
- SpirvImageEmitter.cpp: main's Offset operand placed before MinLod.
- boykopovar#304: main's WaveUniformValues (SpirvAnalysis.cpp) replaces astrobot's
  copy in SpirvWaveExchange.cpp.
- Recorder.hpp/.cpp, Draw.hpp, Graphics Draw.cpp, ShaderResources.cpp:
  astrobot's boykopovar#276/boykopovar#277 with its later snapshot work (per-use budgets,
  stale-snapshot refresh, profile counters, boykopovar#410, boykopovar#424, fan GS); boykopovar#409/boykopovar#306
  comments as main has them.
- PacketMemory.cpp: boykopovar#409 as merged plus astrobot's two opt-outs.
- tests: ShaderMemory.cpp takes boykopovar#303's and boykopovar#304's new tests; Recorder.cpp
  takes boykopovar#409's afterRecordedWorkTests and drops main's copies of the
  boykopovar#276/boykopovar#277 tests astrobot already has; Structurizer.cpp keeps boykopovar#413's case.

boykopovar#143 (NGG passthrough) stays as on astrobot: upstream did not touch its
files since the boykopovar#258 revert.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agc libSceAgc* build ci .github shader core/shader

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants