Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Frag depth #1263

Open
wants to merge 14 commits into
base: master
Choose a base branch
from
Open

Frag depth #1263

wants to merge 14 commits into from

Conversation

lusius
Copy link
Contributor

@lusius lusius commented Jan 17, 2025

GLSL Has a writeable global for writing directly to the depthbuffer.

SV_Depth seems to be the same in HLSL.

hxsl/Checker.hx Outdated Show resolved Hide resolved
hxsl/Checker.hx Outdated Show resolved Hide resolved
hxsl/HlslOut.hx Outdated Show resolved Hide resolved
@ncannasse
Copy link
Member

The PR needs several fixes.
Ping @TothBenoit for other comments ?

@TothBenoit
Copy link
Contributor

I quickly tested the changes with this :
class CustomDepth extends hxsl.Shader { static var SRC = { function fragment() { fragDepth = 0.5; } } }
The line is being removed during linker. hasSideEffect(e) in Ast.hx should return true for FragDepth to avoid this.

Also it would be nice to either forbid reading to fragDepth in the checker, since SV_Depth is write-only or create an intermediate value that can be read and rewritten multiple times that will write to fragDepth at the end of the shader.

@lusius
Copy link
Contributor Author

lusius commented Jan 21, 2025

Sure thing, I'll go about fixing that.

@lusius
Copy link
Contributor Author

lusius commented Jan 21, 2025

@TothBenoit I've added a reference for hasSideEffects and had to add a force inclusion in the linker for this to work. But I don't know if this would be the correct way. Also shader doesn't like when I assign a variable instead to fragDepth

class CustomDepth extends hxsl.Shader { static var SRC = { function fragment() { var x = 0.5; fragDepth = x; } } }

Crashes in compiler.

I don't know how to proceed from here.

@ncannasse
Copy link
Member

ncannasse commented Jan 21, 2025 via email

@lusius
Copy link
Contributor Author

lusius commented Jan 21, 2025

@ncannasse I did that and it seems to work fine other than it for some reason can't be assigned a variable.

@lusius
Copy link
Contributor Author

lusius commented Jan 23, 2025

I have tried to add a readdependency but assigned variable still gets filtered out before (i think) dce. I'm trying to get a dependency going marking my variable "x" in testshader above as dependent but so far I have failed.

Do you have any ideas on how to solve this?

@lusius
Copy link
Contributor Author

lusius commented Jan 23, 2025

Ping @TothBenoit , do you have time to help me out here? Would be much appreciated!

@TothBenoit
Copy link
Contributor

TothBenoit commented Jan 24, 2025

Hello,
Your variable is being removed by the DCE. You need to make sure that it is marked as used during the check method of the DCE.
You can add this case to ensure this:

case TBinop(OpAssign, { e : TGlobal(FragDepth) }, e2 ):
	writeTo.push(null, 15);
	check(e2, writeTo, isAffected);
	writeTo.pop();

This will force the DCE to keep expression e2.

However, I just realised that we should only keep the last assignment to fragDepth.
In this code, only the last 2 expressions should be kept

var x = 0.5;
fragDepth = x;
var y = 0.5;
fragDepth = y;

This could be done by marking only the last assignment to fragDepth as having a side effect in the checker, and making sure that the fragDepth assignment has a side effect in the DCE.

@lusius
Copy link
Contributor Author

lusius commented Jan 28, 2025

@TothBenoit @ncannasse

I have updated now ackording to the suggestions. To be able to distinguish between fragdepth writes I had to create a common variable id for it.

function fragment() { var b = 0.3; fragDepth = b; var x = 0.5; fragDepth += x; var y = 0.5; fragDepth = mix(0,y,0.5); var a = 0.1; fragDepth += a; }

    The DCE seems to handle this correct:
    ``
 y = 0.5;
gl_FragDepth = mix(0., y, 0.5);
a = 0.1;
gl_FragDepth += a;
    ``

@TothBenoit
Copy link
Contributor

Just tested it, works fine with GL.

However, it crashes on DirectX 11 and 12. SV_Depth is not a variable, it is a semantic name :
https://learn.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-semantics

You need to declare a new output for the fragment. See FragCoord in HlslOut.hx for a similar case.

@lusius
Copy link
Contributor Author

lusius commented Feb 6, 2025

@TothBenoit Thank you for your reply. I have removed the Hlsl-lines due to no knowledge in DX and I have no stable environment to test this properly. Thank you for you invaluable knowledge.

I'm letting the next person do the DX implementation of this.

Are we fine to merge this @ncannasse ?

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