Shader Semantic Question

I’m in charge of porting a piece of non-game software that uses XNA for embedded graphics to Monogame. The original code is not mine, and I’ve never worked with shaders before.

The code uses HLSL shaders, which we want to compile and run on Mac, Windows, and Linux. So I gather that the Shader Model has to stay less than or equal to 3.0, and properly translate into GLSL through MojoShader. Right now, one of the shaders is failing to compile but the Pipeline tool doesn’t return a proper explanatory message–Here’s what we get:

C:/Users/u0920639/MonoViking/Clients/Viking/VikingMonogameGraphics/VikingGraphicsWindowsGL/Content/../../Content/RoundLine.fx
C:/Users/u0920639/MonoViking/Clients/Viking/VikingMonogameGraphics/VikingGraphicsWindowsGL/Content/../../Content/RoundLine.fx: error: Processor 'EffectProcessor' had unexpected failure!
System.Exception: invalid register for relative address
   at TwoMGFX.ShaderData.CreateGLSL(Byte[] byteCode, Boolean isVertexShader, List`1 cbuffers, Int32 sharedIndex, Dictionary`2 samplerStates, Boolean debug)
   at TwoMGFX.EffectObject.CreateShader(ShaderInfo shaderInfo, String shaderFunction, String shaderProfile, Boolean isVertexShader, String& errorsAndWarnings)
   at TwoMGFX.EffectObject.CompileEffect(ShaderInfo shaderInfo, String& errorsAndWarnings)
   at Microsoft.Xna.Framework.Content.Pipeline.Processors.EffectProcessor.Process(EffectContent input, ContentProcessorContext context)
   at Microsoft.Xna.Framework.Content.Pipeline.ContentProcessor`2.Microsoft.Xna.Framework.Content.Pipeline.IContentProcessor.Process(Object input, ContentProcessorContext context)
   at MonoGame.Framework.Content.Pipeline.Builder.PipelineManager.ProcessContent(PipelineBuildEvent pipelineEvent)
Build 10 succeeded, 1 failed.

Time elapsed 00:00:01.01.
fail - invalid register for relative address
fail - Reserved bit #2 in source token must be one
fail - instruction token high bit must be zero.
fail - Partial precision result mod in non-pixel shader
fail - Centroid result mod in non-pixel shader
fail - Reserved bit #2 in source token must be one
fail - instruction token high bit must be zero.
fail - instruction token high bit must be zero.
fail - bit #31 in relative address must be set
fail - invalid register for relative address
fail - invalid register for relative address
fail - instruction token high bit must be zero.
fail - bit #31 in relative address must be set
fail - invalid register for relative address
fail - invalid register for relative address
fail - instruction token high bit must be zero.
fail - instruction token high bit must be zero.
fail - Reserved bit #2 in destination token must be one
fail - instruction token high bit must be zero.
fail - Reserved bit #2 in source token must be one
fail - Predicated instruction but not predicate register!
fail - instruction token high bit must be zero.
fail - Centroid result mod in non-pixel shader
fail - bit #31 in relative address must be set
fail - invalid register for relative address
fail - invalid register for relative address
fail - instruction token high bit must be zero.
fail - Partial precision result mod in non-pixel shader
fail - Centroid result mod in non-pixel shader
fail - Reserved bit #2 in source token must be one
fail - instruction token high bit must be zero.
fail - coissue instruction on non-pixel shader
fail - Partial precision result mod in non-pixel shader
fail - Centroid result mod in non-pixel shader
fail - Reserved bit #2 in source token must be one
fail - instruction token high bit must be zero.
fail - Partial precision result mod in non-pixel shader
fail - Centroid result mod in non-pixel shader
fail - Reserved bit #2 in source token must be one
fail - instruction token high bit must be zero.
fail - Partial precision result mod in non-pixel shader
fail - Centroid result mod in non-pixel shader
fail - Reserved bit #2 in source token must be one
fail - instruction token high bit must be zero.
fail - Partial precision result mod in non-pixel shader
fail - Centroid result mod in non-pixel shader
fail - Reserved bit #2 in source token must be one
fail - instruction token high bit must be zero.
fail - Partial precision result mod in non-pixel shader
fail - Centroid result mod in non-pixel shader
fail - Reserved bit #2 in source token must be one
fail - instruction token high bit must be zero.
fail - Partial precision result mod in non-pixel shader
fail - Centroid result mod in non-pixel shader
fail - Reserved bit #2 in source token must be one
fail - instruction token high bit must be zero.
fail - Reserved bit #2 in destination token must be one
fail - Predicated instruction but not predicate register!

Together with the creator of the original code, I’ve narrowed the problem down to several lines where data is retrieved from an array by index. Our theory is that the error comes from giving the wrong semantics to an input variable that is used to index the array.

The index to retrieve is declared in this struct with the semantics of TEXCOORD1. (Personally I don’t know what this means, but it seems to be the problem.)

struct VS_INPUT
{
	float4 pos : POSITION;
	float2 vertRhoTheta : NORMAL;
	float2 vertScaleTrans : TEXCOORD0;
	float instanceIndex : TEXCOORD1;
};

Later on in a function, instanceIndex is used to index an array:

float x0 = instanceData[In.instanceIndex].x;
float y0 = instanceData[In.instanceIndex].y;
float rho = instanceData[In.instanceIndex].z;
float theta = instanceData[In.instanceIndex].w;

We know this is the source of the problem because the following code compiles successfully:

float x0 = 0;
float y0 = 0;
float rho = 0;
float theta = 0;

So the question is, what are the proper semantics to use on the instanceIndex variable to designate it as an integer containing an array index? Does it need to be declared as int or uint?

Thanks in advance for any insights here. And let me know if more information is needed.

Using TEXCOORDN semantics is the correct way to pass per-vertex data. I’ve not tried using a single float before though, so perhaps change instanceIndex to a float2. Also, does the array indexing work if you change it to a constant? Maybe an explicit cast is required there.

Indexing the array with a constant (0) builds fine.

Changing instanceIndex to a float2 yields the following error:

C:\\Users\\u0920639\\MonoViking\\Clients\\Viking\\VikingMonogameGraphics\\Content\\RoundLine.fx(51,26): error X3120: invalid type for index - index must be a scalar, or a vector with the correct number of dimensions

Explicitly casting instanceIndex to uint fails because that cast can only be applied to known-positive values. Applying abs() and then casting to uint yields the original error (invalid register for relative address). Casting to int (whether instanceIndex is float or float2 also yields the original error.