devkitPro / citro3d

Homebrew PICA200 GPU wrapper library for Nintendo 3DS
zlib License
248 stars 35 forks source link

Binding programs without drawing anything can result in inconsistent uniform state #39

Open truecolour opened 7 years ago

truecolour commented 7 years ago
  1. Bind a program with a geometry shader.
  2. Set the first uniform in the geometry shader to value A.
  3. Without rendering anything, bind a different program without a geometry shader.
  4. Set the first uniform in the vertex shader to value B.
  5. Render something. The results will use value A.

Adding a C3D_UpdateUniforms(GPU_GEOMETRY_SHADER) between steps 2 and 3 fixes the problem.

If I understand the internals correctly, the problem is that the C3D_{FV,IV,Bool}UnifDirty flags don't get cleared when binding a new program.

fincs commented 7 years ago

Without rendering anything

That is the problem. Why are you binding a program, then afterwards binding another one without having rendered anything in the first place? Can't you avoid binding the first program since it's not used for rendering?

truecolour commented 7 years ago

Context: I'm adding particle effects to a game I'm working on. The rendering code configures the shading, etc., binds the program, then loops through all particle sources, sets up buffers and calls DrawArrays. Regular objects get drawn afterwards. If there aren't any particle sources, the graphics get glitchy.

So yes, I can easily avoid binding the program at all. But this is really confusing behaviour. If this is intentional, IMO it should be documented somewhere.