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

HXSL: Implement borrow qualifier #916

Merged
merged 2 commits into from Jan 10, 2021

Conversation

Yanrishatum
Copy link
Contributor

Implements @borrow(path.to.Shader) qualifier to variables.
This is essentially reverse of the @shared qualifier and intended only for advanced usage. (As pretty much everything HXSL, frankly.) Lets user-defined shaders to borrow uniforms from other shaders. Does not perform checks for that shader actually being attached and is completely on the conscience of the user to ensure shaders they borrow from are present. This a follow up to #912 as an alternative way to access foreign uniforms.

Usage example

In this shader I already posted before I need to know the texture size of Base2d to perform custom sampling filter transition curve that is specifically made for pixel-art. And "just set texture to what you going to render beforehand" is not a solution.

class PixelartAA extends hxsl.Shader {
	
	static var SRC = {
		
		@borrow(h3d.shader.Base2d) var texture : Sampler2D;
		@var var calculatedUV:Vec2;

		function subpixelAA(uv:Vec2):Vec2 {
			var size = texture.size();
			var deriv = fwidth(uv) * .5;
			var uvmin = (uv - deriv) * size; // top-left edge of the screen pixel
			var uvmax = (uv + deriv) * size; // bottom-right edge of the screen pixel
			var fmax = floor(uvmax);
			var t = (fmax - uvmin) / (uvmax - uvmin) * (fmax - floor(uvmin));
			uv = ((fmax + 0.5 - t) / size);
		}

		function __init__fragment() {
			calculatedUV = subpixelAA(calculatedUV);
		}

	}

}

Reasoning

  1. While I understand that shaders are designed to be fairly isolated and communicate only via shared variables, not once I found myself in a need to have access to some @param, and so far only solution was to make a duplicate param, and ensure that you set it to same value as the one want data from. And this is clearly not a very good solution.
  2. Uniform redundancy is solved this way. If there's something you need to get from uniform that is supplied by another shader in the pipeline - you can borrow it.
  3. While feature is undoubtfully dangerous since it can produce runtime compilation errors - it's a thing to many parts of shader pipeline. I think this is a responsibility of the programmer to ensure that all required shaders are in the pipeline, and if not - its their own fault.
  4. As many HXSL features - this one will be obscure and unknown to many users (unless I document it, ha), and wont affect vast majority of them, but it introduces more control over the shader pipeline to people who want it.
  5. The "name is common hence can't be marked as @shared" is no longer applicable, since borrowing is an explicit action from the user, and it doesn't matter if name is common or not. Especially since it requires to specify which shader it borrows from. I can make it as simple as just @borrow but then it's not very clear what it borrows and from where.

Extra notes

Because of how duplicate name is implemented, common names are a big problem in general for borrow and shared qualifiers, because those checks happen only for first variable, there are edge cases that can be resolved only by accounting for all variables that were renamed due to naming collision. Such as:

// ShaderA
@param var color:Vec4;
// ShaderB
@shared @param var color:Vec4;
// ShaderC
var color:Vec4;
// Output
@param var color:Vec4; // ShaderA
@param var color2:Vec4; // ShaderB
@local var color3:Vec4; // ShaderC
// Expected result
@param var color:Vec4; // ShaderA
@param var color2:Vec4; // ShaderB + ShaderC

This wont compile btw, because color3 is never assigned. Reverse is applicable as well, with @borrow(ShaderB) var color:Vec4;
This is obviously because ShaderB, which shares its uniform was processed after ShaderA, which occupied the color ID, causing it to be renamed into color2, and by the time ShaderC get processed and expects the shared uniform from ShaderB - it gets the color that is not marked as shared, causing it to be considered unique, disregarding that color2 is shared.

@trethaller
Copy link
Member

Note to @ncannasse : I didn't know @shared existed and wasn't able to find any usage of it in heaps, hide, Northgard, Darksburg, and newer projects. So backward-compat doesn't seem like a big issue

@skial skial mentioned this pull request Dec 16, 2020
1 task
hxsl/Linker.hx Outdated Show resolved Hide resolved
hxsl/Linker.hx Outdated
@@ -88,19 +110,19 @@ class Linker {
}
// add a new field
if( ft == null )
fl2.push(allocVar(f1,p).v);
fl2.push(allocVar(f1,p, null, null, shaderName).v);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't like much that shaderName seems to be requested to track all vars correctly, and yet it's an optional parameter at the end of parameters. Move it either as first optional parameter and eventually make it not-optional.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll move it, but I can't make it non-optional, because the shader name information is not available in all cases where variables are allocated (i.e. inside functions) and borrowing supposed to work only for params anyway, hence its passed only when allocating the general variables and omitted for everything else.

hxsl/Ast.hx Show resolved Hide resolved
@ncannasse
Copy link
Member

Apart from my review in code, i'm fine with the feature. Might require some documentation https://github.com/HeapsIO/heaps/wiki/HXSL#variable-kind

Simplify mergeVar borrow check
Move shaderName argument.
@Yanrishatum
Copy link
Contributor Author

Ping. Also regarding docs: I'll update it when PR's merged, so no worries.

@ncannasse ncannasse merged commit ec0f6ee into HeapsIO:master Jan 10, 2021
@ncannasse
Copy link
Member

Thanks ! merged

@Yanrishatum Yanrishatum deleted the feature_hxsl_borrow branch January 11, 2021 05:43
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.

None yet

3 participants