LukasBanana/XShaderCompiler

GetDimensions() -> textureSize()

slembcke opened this issue · 4 comments

Looks like this is trying to substitute the function directly.

HLSL input:
MainTexture.GetDimensions(0, size.x, size.y);

GLSL output:
textureSize(MainTexture, 0, size.x, size.y);

Had some difficulty tracking down where the actual transform happens for this.

You're right, the compiler uses the direct approach by default.
For those situations a special case must be implemented.
I wonder why I missed especially this function.

I guess a wrapper function here is unavoidable, due to the output parameters.
E.g. for a worst case scenario like this:

// HLSL
struct SomeStruct {
    uint width;
    uint mafuba;
    uint height;
} someStruct;
MainTexture.GetDimensions(0, someStruct.width, someStruct.height);

The translation without a wrapper function needs at least a temporary variable:

// GLSL
ivec2 temp = textureSize(MainTexture, 0).xy;
someStruct.width = uint(temp.x); // type cast, due to ivec2 vs. uvec2
someStruct.height = uint(temp.y);

Using a wrapper function makes this much easier:

// GLSL
void GetDimensions(sampler2D t, uint lod, out uint w, out uint h) {
    ivec2 s = textureSize(int(lod), t);
    w = uint(s.x);
    h = uint(s.y);
}

/* ... */

GetDimensions(MainTexture, 0, size.x, size.y);

Maybe I can fix this at the weekend.

UPDATE:
I remember why I skipped the transformation of the GetDimensions intrinsic so far:
There are dozens of overloaded versions of this instrinsic, which makes it hard to transform it into an appropriate GLSL intrinsic:
see GetDimensions man page

I started with a new branch to tackle this issue. Unfortunately this is quite a big deal, because GetDimensions and textureSize differ a lot. There are many overloaded variants of GetDimensions and some of them must be translated to multiple GLSL calls like textureSize and textureQueryLevels for instance.

For now, I can only recommend you to pass the texture size information via your constant buffers.

Hmm. That's about what I figured. GetDimensions() is a pretty hairy beast to tame. :-\

For now I've just been hard-coding it as a constant fit's my use case. I can always put it in a constant buffer if I need. Thanks for looking into it.

I'm glad you found a solution.
Unfortunately, I don't have much time for this project right now, due to my study.
But I'll keep this issue open, until it's solved.