Compilation issue & Pixel Shader profile

Jun 15, 2009 at 1:04 PM

Hi,

Just to let people know, I had a compilation issue with the ripple fx, the classical "X5608: Compiled shader code uses too many arithmetic instruction slots (65). Max. allowed by the target (ps_2_0) is 64." I have the March 2009 DirectX SDK, Visual Studio .NET 3.5 + SP1.

Unfortunately, the ShaderBuildTask has the "ps_2_0" shader profile hardcoded in it, so the only solution I found was to modify the ShaderBuildTask. I have added three properties to the Task, so it's more flexible:

  • Profile (a string with the shader profile name, with 'ps_2_0' as the default value)
  • Flags (an int value, with 0 as the default value)
  • EntryPoint (a string with 'main' as the default value).

All these match the DirectX D3DXCompileShader function if you need more information. Now this allows to compile the .fx files with a different shader profile than the default ps_2_0. Here is the new ShaderBuildTask.h:

public ref class PixelShaderCompile : Task
	{
	public:
		PixelShaderCompile()
		{
			_dxLibraryToUse = String::Empty;
			_calculatedDxLibraryToUse = false;
			Profile = "ps_2_0";
			EntryPoint = "main";
			Flags = 0;
		}


		[Required]
		property array<ITaskItem^>^ Sources;

		[Output]
		property array<ITaskItem^>^ Outputs
		{
			array<ITaskItem^>^ get()
			{
				return _outputs->ToArray();
			}

			void set(array<ITaskItem^>^ value)
			{
				_outputs->AddRange(value);
			}
		};

		virtual bool Execute() override;

		property String^ Profile;
		property String^ EntryPoint;
		property Int32 Flags;

	private:
		String^ GetDxLibraryToUse();


		List<ITaskItem^>^ _outputs;
		String^ _dxLibraryToUse;
		bool _calculatedDxLibraryToUse;
	};
}
And an extract from what I hav changed in the ShaderBuildTask.cpp:
			LPCSTR shaderTextLPCSTR = context->marshal_as<LPCSTR>(shaderText);
			LPCSTR shaderProfileLPCSTR = context->marshal_as<LPCSTR>(Profile);
			LPCSTR shaderEntryPointLPCSTR = context->marshal_as<LPCSTR>(EntryPoint);
			LPD3DXBUFFER compiledShader;
			LPD3DXBUFFER errorMessages;

			int size = shaderText->Length;

			ShaderCompilerType shaderCompiler = ::D3DXCompileShader;

			// Try to get the latest if the DX SDK is installed.  Otherwise, back up to the statically linked version.
			String^ libraryToLoad = GetDxLibraryToUse();
			CString libraryToLoadAsCString(libraryToLoad);

			HMODULE dxLibrary = ::LoadLibrary((LPCWSTR)libraryToLoadAsCString); 
			bool gotDynamicOne = false;
			if (dxLibrary != NULL)
			{
				FARPROC sc = ::GetProcAddress(dxLibrary, "D3DXCompileShader");
				shaderCompiler = (ShaderCompilerType)sc;
				gotDynamicOne = true;
			}

			HRESULT compileResult = 
				shaderCompiler(
					shaderTextLPCSTR, 
					size, 
					NULL, // pDefines
					NULL, // pIncludes
					shaderEntryPointLPCSTR, // entrypoint
					shaderProfileLPCSTR, // profile
					Flags, // compiler flags
					&compiledShader,
					&errorMessages,
					NULL   // constant table output
					);

Now, you also have to update the .csproj (Right Click in VS, Unload project, Edit Project...), add the Profile attribute to the .csproj, like this:
...    <PixelShaderCompile Sources="@(Effect)" Profile="ps_2_a">
      <Output TaskParameter="Outputs" ItemName="Resource" />
    </PixelShaderCompile> ...

Now, when I use the ps_2_a profile instead of ps_2_0, I can compile successfully!
Jun 15, 2009 at 8:54 PM

Unfortunately, this was useless, as WPF Pixel Shader wrappers only supports "ps_2_0" profile! At runtime, if you use another profile, you will get an error. Too bad!

Jul 2, 2009 at 5:03 AM

Is there any other way around this?  I've installed the build task, DirectX SDK, all the Silverlight 2 and 3 things, but I'm getting the 65 max instructions as spelled out in the first post.  Any push in the right direction would help a ton.

Jul 2, 2009 at 7:32 AM

Hi,

I suppose the ripple.fx code needs to be changed. Since I did not need it, I just removed it from my solution and recompiled without it.

Jul 2, 2009 at 7:21 PM

I am getting this error as well. It seems that the latest version of fxc.exe ... causes the Ripple effect to cross the Shader 2.0 boundary.

Someone needs to modify the Ripple.fx file so that it compiles under the boundary ... or figure out why the latest version of the fxc compiler ... is causing this to happen.

In the meantime, I, as well, am going to rip this baby out of the library.

Jul 31, 2009 at 11:13 PM

I got it to compile by changing line 35 of Ripple.fx to:

float falloff = 1-distance; //saturate(1-distance);

It'll probably result in some distortion in the corners, but it's better than nothing.

Dec 15, 2009 at 4:05 AM

Thank you, sharoz

I blocked by that error in ripple.fx, and now I can run this library~

Dec 15, 2009 at 7:16 AM

Great change to the ShaderTask! Especially now that WPF4 is out in Beta.

Is it possible to submit that code to codeplex and make a new release of the shadertask?