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

Fix MOVC translation with swizzle #33

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

Conversation

MrShoor
Copy link

@MrShoor MrShoor commented Sep 30, 2014

Fix incorrect swizzling for MOVC instruction:

Broken sample:

struct PS_Input {
float4 Pos: SV_Position;
};
struct PS_Output {
float4 Color : SV_Target0;
};
PS_Output PS(PS_Input In) {
PS_Output Out;
Out.Color.xw = 0.0;
Out.Color.yz = fmod(In.Pos.xy, 40.0)/40.0;
return Out;
}

Incorrect result for MOVC:
Output0.y = (floatBitsToInt(Temp[0]).z != 0) ? Temp[0].x : (-Temp[0].x);
Output0.z = (floatBitsToInt(Temp[0]).z != 0) ? Temp[0].x : (-Temp[0].x);

Correct result:
Output0.y = (floatBitsToInt(Temp[0]).z != 0) ? Temp[0].x : (-Temp[0].x);
Output0.z = (floatBitsToInt(Temp[0]).w != 0) ? Temp[0].y : (-Temp[0].y);

MrShoor and others added 30 commits September 30, 2014 15:55
this case will cast to 0.0:
intBitsToFloat(int(0xBECCCCCDu));

this case will cast to -0.4:
uint q = 0xBECCCCCDu;
intBitsToFloat(int(q));

this case will cast to 0.0 again:
const uint q = 0xBECCCCCDu;
intBitsToFloat(int(q));
For example instruction:
ftoi r0.yz, r0.yyzy
Will translate into:
Temp[0].yz = intBitsToFloat(ivec4(Temp[0].yyzy).xy);
Instead correct translate:
Temp[0].yz = intBitsToFloat(ivec4(Temp[0].yyzy).yz);
lt r2.zw, l(0.000000, 0.000000, 0.500000, 0.500000), |v4.xxxy|
was:
Temp[2].zw = uintBitsToFloat(uvec2(lessThan(vec4(intBitsToFloat(0x0), intBitsToFloat(0x0), intBitsToFloat(0x3F000000), intBitsToFloat(0x3F000000)), abs(Input4.xxxy))) * 0xFFFFFFFFu);
should be:
Temp[2].zw = uintBitsToFloat(uvec2(lessThan(vec4(intBitsToFloat(0x0), intBitsToFloat(0x0), intBitsToFloat(0x3F000000), intBitsToFloat(0x3F000000)), abs(Input4.xxxy)).zw) * 0xFFFFFFFFu);
…for resources

- new flag "HLSLCC_FLAG_PREFER_BINDINGS" that causes the compiler to use bindings (rather than locations) for all resources
- another flag, "HLSLCC_FLAG_ASSIGN_DESCRIPTOR_SET" uses the set qualifier to distinguish between resource bindings and constant buffer bindings
- this is intended to be used when compiling HLSL -> SPIR-V (via GLSL).
- in order to support float3x4/float4x3 type matrices
…l shaders with higher GLSL version numbers

- it's not clear to me what the intention of this line is
- however, it causes a compile error when attempting to compile the result to SPIR-V (which doesn't support subroutines)
…erly

- new CallUnaryOp, which duplicates the behaviour of CallBinaryOp function (but for unary operations)
- this allows the INEG instruction (which is translated as X = 0 - A) to deal with complex swizzling operations, as well as casting (when the register types are not integers)
- previously, textureSize was always used for RESINFO, regardless of the type of the object we were querying
- UAV declarations are translated into "image" types, and so size queries should use the corresponding function, "imageSize"
- this only works when targetting GLSL 4.3 (which is the standard that adds imageSize)
	- when targetting early languages, using RESINFO with a UAV will result in uncompilable code
- this extension renames gl_VertexID -> gl_VertexIndex and gl_InstanceID -> gl_InstanceIndex
- this is required when using the GLSL -> SPIR-V path
- this is required when doing a depth compare gather on an array of 2d textures (for example)
- previously, this was implemented for some variations of the GATHER instruction
- this change uses the same logic for all variations
…verlap on the same location

- now, all output locations get a temporary "vec4"
- we copy from those vec4 values to the actual output values in a fixup step at the end of the shader
- previously there was an attempt at this behaviour with #defines
	- however, this required declaring one of the output variables as a vec4 (even if really wasn't)
	- this solution handles more cases and results in a shader interface that better matches the original HLSL code
- there may be issues with types largers than a vec4 (such as a matrix)
- currently this is only supported for vertex shader outputs... but it could be made more general and used for other shader types
…e destination

- previously, RESINFO instruction only supported some "mask" type swizzle pattern for the destination
- this adds support for all swizzle patterns
- added a new function that can calculate the order of the components referenced by a given swizzle pattern
	- that is, it converts the swizzle values into an array of 4 ints, where each int references either x, y, z or w
- previously all shader inputs would be 4 component vectors
- this could cause shader linking errors now that vertex shaders can output fewer components
- this change uses the "component" layout attribute and uses the correct sized vector types
code:
  uvec4 Input7
  Input7.x = uint(gl_FrontFacing);

cause: error C7011: implicit cast from "int" to "uint"
at least at NVidia GF960
… binding points and descriptor set indices

- Clients can use the callback function, EvaluateBindingFn, to select any binding, descriptor set, or location for HLSL resources
	- clients get access to the type, HLSL binding register information and name with which to make an assignment
- this is important for Vulkan, were we need to assign descriptor sets to resources
- depreciated the previous flags, HLSLCC_FLAG_PREFER_BINDINGS & HLSLCC_FLAG_ASSIGN_DESCRIPTOR_SET, since this is much more powerful solution
…y GL_KHR_vulkan_glsl)

- this is useful when compiling to Vulkan
- when using the "Load" method in texture objects in HLSL, we need to use a dummy sampler in the generated GLSL
	- this appears to only be required in order to compile... the sampler may have no effect on the output
	- the dummy sampler is bound to s16 by default; but it can be rebound using the bind evaluation function
… function for buffers

- this allows us to distinquish between StructuredBuffer types and ConstantBuffers
- both types have a "ConstantBuffer" object
- but the true type can be determined from the "eType" member of the ResourceBinding object
…turedBuffers

- this allows the RWStructedBuffer's "buffer" object to contain the true name
- that name will be preserved in the SPIR-V code and allows us to get at it using reflection on the SPIR-V bytecode
…NFO instructions

- these instructions were interpreted incorrectly for cases where the destination swizzle was not a contiguous sequence from .x
- the new method handles more cases...
	- but this is only applied to a few instructions
	- it should really effect many instructions!
- selecting a #define for languages that support scalar swizzle, or falling back to old solution otherwise
- Sometimes a single instruction will use values from multiple constant buffer variables.
	- So, for example, a constant buffer might look like this:
		cbuffer Buffer { float3 Vector; float Scalar; }
	- Now consider the following statement:
		variable = float4(Vector, Scalar);
	- this can become a single instruction, because both Vector and Scalar are packed into the same 4d vector in the cbuffer
- new code for loading from a cbuffer that handles these cases
- also some improvements to the swizzling code to handle more cases
djewsbury and others added 21 commits May 17, 2016 11:51
…enabled

- an instance name is required using the layout(push_constant) qualifier
- so we use an instance name for all cbuffers to cover this case
…Hull shader)

Fixes the following error seen on an NVIDIA driver.

Number components of parameters for domain shader should match with number components of input parameters of fragment shader
…ta type

HS_CTRL_POINT_PHASE require post shader code phase (because it contain writing to gl_out)
SetDataTypes current working wrong, because for case:
   8: mov r0.x, vForkInstanceID.x
   9: mov o[r0.x + 0].x, l(5.000000)
will generated incorrect code:
        //MOV
        Temp_int[0].x = ivec4(floatBitsToInt(forkInstanceID)).x; // writing to Temp_int
        //MOV
        Output0[int(Temp[0].x)].x = vec4(immediateConstBufferF(int(Temp_int[0].x)).x).x; // but reading from Temp
due psOperand->psSubOperand[0]->aeDataType == SVT_FLOAT of destination operand o[r0.x + 0].x
vec1 Input6;
//....
Temp[123] = Input6.xxx + Input3.xyz;
should be represented as:
vec1 Input6;
//....
Temp[123] = vec3(Input6.x) + Input3.xyz;
fix: impossible assign vec1 to float
fix input declaraion crashes
upd. for vertex shaders only
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.

2 participants