Skip to content

Fix YUV->RGB compute pipeline never executing on Godot 4.7 (push constant size) - #77

Merged
EIREXE merged 1 commit into
EIRTeam:masterfrom
shanyuduo:fix/compute-push-constant-size-godot47
Oct 7, 2026
Merged

EIREXE merged 1 commit into
EIRTeam:masterfrom
shanyuduo:fix/compute-push-constant-size-godot47

Conversation

@shanyuduo

Copy link
Copy Markdown
Contributor

Problem

Godot 4.7's RenderingDevice now strictly validates the push constant size against what the compute shader declares. yuv_to_rgb.glsl declares a 4-byte push constant (bool use_alpha), but FFmpegVideoStreamPlayback::draw() uploads the full 16-byte padded struct (PushConstant { uint32_t use_alpha; uint8_t padding[11]; }).

compute_list_set_push_constant() is therefore rejected on every frame:

ERROR: This compute pipeline requires (4) bytes of push constant data, supplied: (16)
ERROR: The shader in this pipeline requires a push constant to be set before drawing, but it's not present.

and the pipeline never executes, so decoded YUV frames are never converted: video shows nothing under the Forward+/Mobile renderers on Godot 4.7+ (Vulkan logs the error every frame; D3D12 fails silently).

This is the same issue reported in #76 — @EIREXE identified the breaking RD API change there, but the fix hasn't landed yet, so this PR proposes it.

Fix

Pass only the 4 bytes the shader actually declares, skipping the struct padding:

 	PackedByteArray push_constant_data;
-	push_constant_data.resize(sizeof(push_constant));
-	memcpy(push_constant_data.ptrw(), &push_constant, push_constant_data.size());
+	// Godot 4.7's RenderingDevice strictly validates the push constant size
+	// against what the compute shader declares (4 bytes here: bool use_alpha).
+	// Uploading the padded 16-byte struct gets the call rejected on every
+	// frame, so the YUV->RGB pipeline never executes and video never renders
+	// in Forward+/Mobile on Godot 4.7+. Pass only the declared 4 bytes.
+	push_constant_data.resize(4);
+	memcpy(push_constant_data.ptrw(), &push_constant, 4);

This stays correct on older Godot versions, where the check only requires the upload to be at least the declared size.

Verification

  • Godot 4.7.2 stable, Forward+, both Vulkan and D3D12, Intel iGPU (RaptorLake-S):
    a 1440p@120 H.264 video renders correctly and the per-frame push constant errors are
    gone (0 errors, previously 2 errors per rendered frame).
  • Built via gdextension_build SCons pipeline (mingw gcc 16.2, ffmpeg_path pointing
    at the godot FFmpeg build);
    both template_debug and template_release dlls verified in a real project.

Godot 4.7's RenderingDevice now strictly validates the push constant
size against what the compute shader declares. yuv_to_rgb.glsl declares
a 4-byte push constant (bool use_alpha), but
FFmpegVideoStreamPlayback::draw() uploads the full 16-byte padded
struct (PushConstant { uint32_t use_alpha; uint8_t padding[11]; }).

compute_list_set_push_constant() is therefore rejected on every frame
("This compute pipeline requires (4) bytes of push constant data,
supplied: (16)") and the pipeline never executes, so decoded YUV frames
are never converted: video shows nothing under the Forward+/Mobile
renderers on Godot 4.7+ (Vulkan logs the error every frame; D3D12
fails silently). Reproduced on Godot 4.7.2 stable; see issue EIRTeam#76.

Pass only the 4 bytes the shader actually declares, skipping the
padding. This stays correct on older Godot versions, where the check
only requires the upload to be at least the declared size.

Verified on Godot 4.7.2 stable / Forward+ (Vulkan and D3D12, Intel
iGPU): 1440p@120 H.264 video renders correctly and the per-frame push
constant errors are gone (0 errors). Built via gdextension_build
SCons pipeline with mingw gcc 16.2.
@spaceyspacestar

Copy link
Copy Markdown

This fix works great.
Using: Godot 4.8.dev4.mono using Forward+, tested on both d3d12 and Vulkan

@EIREXE

EIREXE commented Oct 6, 2026

Copy link
Copy Markdown
Contributor

My apolocheese for the delay, I will review it

@EIREXE
EIREXE merged commit 84ea333 into EIRTeam:master Oct 7, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants