Cannot create D3D9 pixel shader from microcode [SOLVED]

Problems building or running the engine, queries about how to use features etc.
Oogst
OGRE Expert User
OGRE Expert User
Posts: 1067
Joined: Mon Mar 29, 2004 8:49 pm
Location: the Netherlands
x 43

Cannot create D3D9 pixel shader from microcode [SOLVED]

Post by Oogst »

Some users of Proun are reporting an error to me regarding certain pixel shaders. I am not getting this error myself, so it is difficult for me to find the cause. This is the error they are getting:
OGRE EXCEPTION(3:RenderingAPIException): Cannot create D3D9 pixel shader Cg_DoF_SM3_64samples_FP from microcode. in D3D9GpuFragmentProgram::loadFromMicrocode at ..\..\..\ogre\RenderSystems\Direct3D9\src\OgreD3D9GpuProgram.cpp (line 369)
This seems to only happen on some Ati cards and I have no clue why. I read somewhere that this error was linked to number of instructions in a shader, but this is shader model 3, so that shouldn't be a problem, right?

This is the shader definition:

Code: Select all

fragment_program Cg_DoF_SM3_64samples_FP cg
{
	source DoFPostEffect.cg
	entry_point DoF_SM3_64samples_FP
	profiles ps_3_0

	default_params
	{
		param_named size			float 0.012
		param_named halfSize		float 0.006
		param_named hdriMultiplier	float 2.0
	}
}
And this is the actual shader (removed similar lines to save scrolling):

Code: Select all

void DoF_SM3_64samples_FP
	(
		float2 uv : TEXCOORD0,
		
		out float4 oColour : COLOR,

		uniform sampler2D	textureFullRes : TEXUNIT0,
		uniform float		size,
		uniform float		halfSize,
		uniform float		hdriMultiplier
	)
{
	float2 taps[64] = {float2(0.130265, -0.26094),
						float2(0.323249, 0.269765),
						...
						float2(-0.180269, -0.364196),
						float2(0.386136, -0.0523022)};

	float lengths[64] = {0.291648,
						0.421026,
						...
						0.406369,
						0.389662};

	//The central tap that defines the strength of the blur on this pixel
	float4 tapCentre = tex2D(textureFullRes, uv);

	//calculate the size of the blur on this pixel
	float sizeThisTap = size * tapCentre.a;

	oColour = tapCentre;

	//division is used to normalize the final colour, so it is the
	//addition of the weights for all taps.
	float division = 1;

	int i;
	for (i = 0; i < 64; ++i)
	{
		float4 tapColour = tex2D(textureFullRes, uv + sizeThisTap * taps[i]);
		float maximumAllowedDistance = tapColour.a * halfSize;

		if (lengths[i] * size <= maximumAllowedDistance)
		{
			division += 1;
			oColour += tapColour;
		}
	}

	oColour = oColour * hdriMultiplier / division;
}
I hope someone here knows what I am doing wrong here! Thanks in advance! :)
Last edited by Oogst on Mon Jun 27, 2011 9:45 pm, edited 1 time in total.
My dev blog
Awesomenauts: platforming MOBA (PC/Mac/Linux/XBox360/X1/PS3/PS4)
Blightbound: coop online dungeon crawler (PC)
Swords & Soldiers: side-scrolling RTS (Switch/PS3/Wii/PC/Mac/Linux/iPhone/iPad/Android)
Proun: abstract racing game (PC)
Cello Fortress: mixing game and live cello performance
The Ageless Gate: cello album
User avatar
_tommo_
Gnoll
Posts: 677
Joined: Tue Sep 19, 2006 6:09 pm
x 5

Re: Cannot create D3D9 pixel shader from microcode

Post by _tommo_ »

If I understood correctly you are loading precompiled (where, by whom?) microcode instead of parsing the shader...
as a pure gut feeling, being a microcode tied to a particular ISA, could be that some drivers are unable to load some microcode ops on some lesser cards with an "incomplete" ISA.

You could try to send them a version that fallbacks to compiling from shader code in case of errors and see if it works?
Maybe the driver is able to compile to simpler instructions on cheaper GPUs.
OverMindGames Blog
IndieVault.it: Il nuovo portale italiano su Game Dev & Indie Games
Oogst
OGRE Expert User
OGRE Expert User
Posts: 1067
Joined: Mon Mar 29, 2004 8:49 pm
Location: the Netherlands
x 43

Re: Cannot create D3D9 pixel shader from microcode

Post by Oogst »

I am using what is above, so I am not using any precompiled microcode. Actually, I don't even know what that is exactly! :shock: The shaders are just included with the game as text-source-files.
My dev blog
Awesomenauts: platforming MOBA (PC/Mac/Linux/XBox360/X1/PS3/PS4)
Blightbound: coop online dungeon crawler (PC)
Swords & Soldiers: side-scrolling RTS (Switch/PS3/Wii/PC/Mac/Linux/iPhone/iPad/Android)
Proun: abstract racing game (PC)
Cello Fortress: mixing game and live cello performance
The Ageless Gate: cello album
User avatar
syedhs
Silver Sponsor
Silver Sponsor
Posts: 2703
Joined: Mon Aug 29, 2005 3:24 pm
Location: Kuala Lumpur, Malaysia
x 51

Re: Cannot create D3D9 pixel shader from microcode

Post by syedhs »

It may take a while to solve this problem, so probably the best thing is to disable microcode by GpuProgramManager::getSingleton().setSaveMicrocodesToCache(false) before loading any resource. More information can be found here:- http://www.ogre3d.org/forums/viewtopic. ... =microcode
A willow deeply scarred, somebody's broken heart
And a washed-out dream
They follow the pattern of the wind, ya' see
Cause they got no place to be
That's why I'm starting with me
User avatar
_tommo_
Gnoll
Posts: 677
Joined: Tue Sep 19, 2006 6:09 pm
x 5

Re: Cannot create D3D9 pixel shader from microcode

Post by _tommo_ »

Oogst wrote:I am using what is above, so I am not using any precompiled microcode. Actually, I don't even know what that is exactly! :shock: The shaders are just included with the game as text-source-files.
Microcode is when you do not parse the shader, but you do load a precompiled binary form generated by the driver after previous parses...
could be that you inadvertently included the microcodes in your redist?
Or maybe the AMD drivers are just buggy (as usual) and can't chew the microcode that they build.

If loading times aren't an issue, you could just kill that, as syedhs says.
OverMindGames Blog
IndieVault.it: Il nuovo portale italiano su Game Dev & Indie Games
tommytom
Gnoblar
Posts: 8
Joined: Sun Jun 26, 2011 4:38 am
x 1

Re: Cannot create D3D9 pixel shader from microcode

Post by tommytom »

I was the one with the error.
If you need more info from me, let me know.

I'll dump more ogre.log info here since it wont matter about cluttering it up here.

Code: Select all

22:30:23: CPU Identifier & Features
22:30:23: -------------------------
22:30:23:  *   CPU ID: GenuineIntel: Intel(R) Core(TM)2 Duo CPU     E4400  @ 2.00GHz
22:30:23:  *      SSE: yes
22:30:23:  *     SSE2: yes
22:30:23:  *     SSE3: yes
22:30:23:  *      MMX: yes
22:30:23:  *   MMXEXT: yes
22:30:23:  *    3DNOW: no
22:30:23:  * 3DNOWEXT: no
22:30:23:  *     CMOV: yes
22:30:23:  *      TSC: yes
22:30:23:  *      FPU: yes
22:30:23:  *      PRO: yes
22:30:23:  *       HT: no

Code: Select all

22:30:23: RenderSystem Name: Direct3D9 Rendering Subsystem
22:30:23: GPU Vendor: ati
22:30:23: Device Name: Monitor-1-Radeon X1300/X1550 Series
22:30:23: Driver Version: 8.14.10.647
22:30:23:  * Fixed function pipeline: yes
22:30:23:  * Hardware generation of mipmaps: yes
22:30:23:  * Texture blending: yes
22:30:23:  * Anisotropic texture filtering: yes
22:30:23:  * Dot product texture operation: yes
22:30:23:  * Cube mapping: yes
22:30:23:  * Hardware stencil buffer: yes
22:30:23:    - Stencil depth: 8
22:30:23:    - Two sided stencil support: yes
22:30:23:    - Wrap stencil values: yes
22:30:23:  * Hardware vertex / index buffers: yes
22:30:23:  * Vertex programs: yes
22:30:23:  * Number of floating-point constants for vertex programs: 256
22:30:23:  * Number of integer constants for vertex programs: 16
22:30:23:  * Number of boolean constants for vertex programs: 16
22:30:23:  * Fragment programs: yes
22:30:23:  * Number of floating-point constants for fragment programs: 224
22:30:23:  * Number of integer constants for fragment programs: 16
22:30:23:  * Number of boolean constants for fragment programs: 16
22:30:23:  * Geometry programs: no
22:30:23:  * Number of floating-point constants for geometry programs: 0
22:30:23:  * Number of integer constants for geometry programs: 0
22:30:23:  * Number of boolean constants for geometry programs: 0
22:30:23:  * Supported Shader Profiles: hlsl ps_1_1 ps_1_2 ps_1_3 ps_1_4 ps_2_0 ps_2_a ps_2_b ps_2_x ps_3_0 vs_1_1 vs_2_0 vs_2_a vs_2_x vs_3_0
22:30:23:  * Texture Compression: yes
22:30:23:    - DXT: yes
22:30:23:    - VTC: no
22:30:23:    - PVRTC: no
22:30:23:  * Scissor Rectangle: yes
22:30:23:  * Hardware Occlusion Query: yes
22:30:23:  * User clip planes: yes
22:30:23:  * VET_UBYTE4 vertex element type: yes
22:30:23:  * Infinite far plane projection: yes
22:30:23:  * Hardware render-to-texture: yes
22:30:23:  * Floating point textures: yes
22:30:23:  * Non-power-of-two textures: yes (limited)
22:30:23:  * Volume textures: yes
22:30:23:  * Multiple Render Targets: 4
22:30:23:    - With different bit depths: no
22:30:23:  * Point Sprites: yes
22:30:23:  * Extended point parameters: yes
22:30:23:  * Max Point Size: 10
22:30:23:  * Vertex texture fetch: no
22:30:23:  * Number of world matrices: 0
22:30:23:  * Number of texture units: 8
22:30:23:  * Stencil buffer depth: 8
22:30:23:  * Number of vertex blend matrices: 0
22:30:23:  * Render to Vertex Buffer : no
22:30:23:  * DirectX per stage constants: no
Full log: http://pastebin.com/MMPB7k9s

If you need me to try test builds, etc, please hit me up on messenger. tommytom2k2 on most. Or send my an email on hotmail (same name).
User avatar
Jabberwocky
OGRE Moderator
OGRE Moderator
Posts: 2819
Joined: Mon Mar 05, 2007 11:17 pm
Location: Canada
x 218

Re: Cannot create D3D9 pixel shader from microcode

Post by Jabberwocky »

Nicely done tommytom,
I hope I have players as helpful as you once my game is finished.
syedhs wrote:It may take a while to solve this problem, so probably the best thing is to disable microcode by GpuProgramManager::getSingleton().setSaveMicrocodesToCache(false) before loading any resource.
This setSaveMicrocodesToCache stuff is Ogre 1.8 only. I'm guessing Proun is 1.7 or less.
_tommo_ wrote:If I understood correctly you are loading precompiled...
I don't think this is correct either.
I just ran my game and put a breakpoint in D3D9GpuVertexProgram::loadFromMicrocode.
Like Oogst, I just load my shader source from text.
But loadFromMicrocode is called anyway.
Here's the stack, the important part being the top 2 functions.

Code: Select all

>	RenderSystem_Direct3D9_d.dll!Ogre::D3D9GpuVertexProgram::loadFromMicrocode(IDirect3DDevice9 * d3d9Device=0x06d9b080, ID3DXBuffer * microcode=0x0a105d90)  Line 239	C++
 	RenderSystem_Direct3D9_d.dll!Ogre::D3D9GpuProgram::loadFromSource(IDirect3DDevice9 * d3d9Device=0x06d9b080)  Line 205 + 0x1a bytes	C++
 	RenderSystem_Direct3D9_d.dll!Ogre::D3D9GpuProgram::loadImpl(IDirect3DDevice9 * d3d9Device=0x06d9b080)  Line 155	C++
 	RenderSystem_Direct3D9_d.dll!Ogre::D3D9GpuProgram::loadImpl()  Line 127 + 0xc bytes	C++
 	OgreMain_d.dll!Ogre::Resource::load(bool background=false)  Line 239 + 0xf bytes	C++
 	OgreMain_d.dll!Ogre::HighLevelGpuProgram::loadImpl()  Line 57 + 0x22 bytes	C++
 	OgreMain_d.dll!Ogre::Resource::load(bool background=false)  Line 239 + 0xf bytes	C++
 	OgreMain_d.dll!Ogre::GpuProgramUsage::_load()  Line 113 + 0x28 bytes	C++
 	OgreMain_d.dll!Ogre::Pass::_load()  Line 1229	C++
 	OgreMain_d.dll!Ogre::Technique::_load()  Line 595	C++
 	OgreMain_d.dll!Ogre::Material::loadImpl()  Line 162	C++
 	OgreMain_d.dll!Ogre::Resource::load(bool background=false)  Line 239 + 0xf bytes	C++
As you can see, loadFromSource calls loadFromMicrocode.

Code: Select all

	void D3D9GpuProgram::loadFromSource(IDirect3DDevice9* d3d9Device)
	{
		D3D9_DEVICE_ACCESS_CRITICAL_SECTION


		// Populate compile flags
        DWORD compileFlags = 0;

		// Create the shader
		// Assemble source into microcode
		LPD3DXBUFFER microcode;
		LPD3DXBUFFER errors;
		HRESULT hr = D3DXAssembleShader(
			mSource.c_str(),
			static_cast<UINT>(mSource.length()),
			NULL,               // no #define support
			NULL,               // no #include support
			compileFlags,       // standard compile options
			&microcode,
			&errors);

		if (FAILED(hr))
		{
			String message = "Cannot assemble D3D9 shader " + mName + " Errors:\n" +
				static_cast<const char*>(errors->GetBufferPointer());
			errors->Release();
			OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, message,
				"D3D9GpuProgram::loadFromSource");
		}
	
		loadFromMicrocode(d3d9Device, microcode);		

		SAFE_RELEASE(microcode);
		SAFE_RELEASE(errors);
	}
_tommo_ wrote: Or maybe the AMD drivers are just buggy (as usual) and can't chew the microcode that they build.
Something like this seems to be the case.
As far as I can understand looking at the code, the microcode comes from a call to D3DXAssembleShader, which must be returning S_OK (or else we'd hear about it in the log), but then the subsequent call to IDirect3DDevice9::CreateVertexShader using this microcode is failing.

I notice that the exception / log does not indicate the error returned from IDirect3DDevice9::CreateVertexShader. It should.

Looking here:
http://msdn.microsoft.com/en-us/library ... 85%29.aspx

It appears that this function can fail for these reasons:
If the method succeeds, the return value is D3D_OK. If the method fails, the return value can be one of the following: D3DERR_INVALIDCALL, D3DERR_OUTOFVIDEOMEMORY, E_OUTOFMEMORY.
Maybe the user's computer is out of video memory.
I would consider compiling a new version of the ogre dll to send to this user, that includes the error returned from CreateVertexShader.
Specifically, in
file: OgreD3D9GpuProgram.cpp
function: D3D9GpuVertexProgram::loadFromMicrocode

change the error handling here to spit out the value of the variable "hr":

Code: Select all

			hr = d3d9Device->CreateVertexShader( 
				static_cast<DWORD*>(microcode->GetBufferPointer()), 
				&pVertexShader);

			if (FAILED(hr))
			{
				OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, 
					"Cannot create D3D9 vertex shader " + mName + " from microcode",
					"D3D9GpuVertexProgram::loadFromMicrocode");
	            
			}
Image
User avatar
Jabberwocky
OGRE Moderator
OGRE Moderator
Posts: 2819
Joined: Mon Mar 05, 2007 11:17 pm
Location: Canada
x 218

Re: Cannot create D3D9 pixel shader from microcode

Post by Jabberwocky »

I'd also be curious how much VRAM tommytom's card has. Oogst, with that info, maybe you can make some guesses if VRAM is the problem, based on how much VRAM you guess Proun might need. You may need to add/update the minimum specs for Proun, or consider adding some sort of texture quality setting.

-- although looking at tommytom's full log, it doesn't look like that much stuff has been loaded yet, so maybe VRAM isn't the culprit.
If you haven't already, it's worth trying the ol' "update your video card drivers" solution.
Image
Oogst
OGRE Expert User
OGRE Expert User
Posts: 1067
Joined: Mon Mar 29, 2004 8:49 pm
Location: the Netherlands
x 43

Re: Cannot create D3D9 pixel shader from microcode

Post by Oogst »

I am indeed using Ogre 1.7 and I'm definitely not going to switch to 1.8 on an already released game, so we will have to find a solution in Ogre 1.7, I'm afraid.

I don't think VRAM can be the problem. One of the users reporting this has a Radeon X1650 which seems to have 256mb RAM. Tommytom has a card from the same series (X1300/1550). I don't think Proun ever has even near to 100mb of textures in memory and even if it did, DirectX would start swapping with RAM if there were too many textures. Also, I have heard from users that ran the game playable on a Geforce FX 5200 (!), so this much more recent Ati should be fine.

@tommytom: how much video memory do you have and how you tried yo update your drivers?
My dev blog
Awesomenauts: platforming MOBA (PC/Mac/Linux/XBox360/X1/PS3/PS4)
Blightbound: coop online dungeon crawler (PC)
Swords & Soldiers: side-scrolling RTS (Switch/PS3/Wii/PC/Mac/Linux/iPhone/iPad/Android)
Proun: abstract racing game (PC)
Cello Fortress: mixing game and live cello performance
The Ageless Gate: cello album
User avatar
dark_sylinc
OGRE Team Member
OGRE Team Member
Posts: 5509
Joined: Sat Jul 21, 2007 4:55 pm
Location: Buenos Aires, Argentina
x 1378

Re: Cannot create D3D9 pixel shader from microcode

Post by dark_sylinc »

First; I would like to see the vertex shader. Make sure it's SM 3.0; this is a requirement from DirectX, not ATI alone! Furthermore there might be an error in the interpolators you're passing

Second, you're doing a tex2D inside a loop. My guess NVIDIA drivers expand the loop by looking at the assembly code, and ATI drivers keep the loop (they both handle the way that is more efficient in their cards).

Doing a tex2D inside a loop or branch is not allowed. Therefore you need to change it like this, so that it use derivatives:

Code: Select all

//Ooops, we should have one derivative per tap (may have mipmaping artifacts, but it's DoF so you shouldn't be using mipmapping), but oh hell... (and we can't calculate derivatives in the loop either)
xDeriv = ddx( uv );
yDeriv = ddx( uv );

int i;
for (i = 0; i < 64; ++i)
{
    float4 tapColour = tex2D(textureFullRes, uv + sizeThisTap * taps[i], xDeriv, yDeriv);
Alternatively, if you want efficiency and you're not using mipmapping at all (nor anisotropic filtering) which is the case in post processing like DoF, you can perform:

Code: Select all

int i;
for (i = 0; i < 64; ++i)
{
    float4 tapColour = tex2Dlod(textureFullRes, (uv + sizeThisTap * taps[i]).xyyy);
From the xyyyy, the xy is used, the other two "yy" can be garbage as long as you don't have mipmaps in the texture you're sampling from.

Cheers
Dark Sylinc

PS: You're probably going to see more useful information if you compile it as HLSL and load from source code in the PC with the video card that is causing trouble. Also ask your user if he may try enabling the DX Debug Runtime, may spill out more info.

PS2: Most pixel shaders survive a tex2D inside a loop only because their loop ends up being expanded. But I guess by having 64 taps, it's probably not being expanded.

PS3: The X1000 ATI series are crap. They don't fully comply 100% with the SM 3.0; you may be hitting an instruction count limit (either in texture samples or ALUs) specific to that model (which would go against the standard SM 3.0), try also lowering the amount of taps (BTW, if you lower the taps, greater chance of having your loop being expanded).

Edit: The log reports "Non-power-of-two textures: yes (limited)" may that be the cause? (textureFullRes not being power of two)
Oogst
OGRE Expert User
OGRE Expert User
Posts: 1067
Joined: Mon Mar 29, 2004 8:49 pm
Location: the Netherlands
x 43

Re: Cannot create D3D9 pixel shader from microcode

Post by Oogst »

Nvidia drivers indeed expand the loop. I looked at the assembly a while ago and it was indeed an expanded loop.

According to documentation, tex2dlod is only supported from sm4.0 and up, so I cannot use that solution. Source: http://http.developer.nvidia.com/Cg/tex2Dlod.html

tex2d with derivatives is supported in all pixels shader models (http://http.developer.nvidia.com/Cg/tex2D.html), but I don't see how that solves the problem: isn't that still a call to tex2d inside a for-loop, wasn't that the problem?

The vertex shader is indeed also Shader model 3. Mixing up models is totally okay on Nvidia cards, by the way, but I already knew it doesn't work on Ati cards, so I checked that. However, the microcode thing is during compiling, right? Isn't this before Ogre combines these shaders for an actual render call? Anyway, here is the vertex shader definition and code:

Code: Select all

vertex_program Cg_DoF_SM3_VP cg
{
	source DoFPostEffect.cg
	entry_point DoF_VP
	profiles vs_3_0

	default_params
	{
		param_named_auto worldViewProjectionMatrix worldviewproj_matrix
	}
}

void DoF_VP
	(
		float4 position : POSITION,
		float2 uv       : TEXCOORD0,
		
		out float4 oPosition : POSITION,
		out float2 oUv	     : TEXCOORD0,
		
		uniform float4x4 worldViewProjectionMatrix
	)
{
	oPosition = mul(worldViewProjectionMatrix, position);
	
	//force position of the vertex to its corner of the screen (the screen is from -1 to 1)
	oPosition.x = step(0.3f, oPosition.x) * 2.0f - 1.0f;
	oPosition.y = step(0.3f, oPosition.y) * 2.0f - 1.0f;

	oUv = uv;
}
My dev blog
Awesomenauts: platforming MOBA (PC/Mac/Linux/XBox360/X1/PS3/PS4)
Blightbound: coop online dungeon crawler (PC)
Swords & Soldiers: side-scrolling RTS (Switch/PS3/Wii/PC/Mac/Linux/iPhone/iPad/Android)
Proun: abstract racing game (PC)
Cello Fortress: mixing game and live cello performance
The Ageless Gate: cello album
Oogst
OGRE Expert User
OGRE Expert User
Posts: 1067
Joined: Mon Mar 29, 2004 8:49 pm
Location: the Netherlands
x 43

Re: Cannot create D3D9 pixel shader from microcode

Post by Oogst »

I tried just unrolling the entire code by hand (only 64 iterations...), now I just need someone to try that! :)

http://www.ronimo-games.com/forum/viewt ... f=7&t=1082
My dev blog
Awesomenauts: platforming MOBA (PC/Mac/Linux/XBox360/X1/PS3/PS4)
Blightbound: coop online dungeon crawler (PC)
Swords & Soldiers: side-scrolling RTS (Switch/PS3/Wii/PC/Mac/Linux/iPhone/iPad/Android)
Proun: abstract racing game (PC)
Cello Fortress: mixing game and live cello performance
The Ageless Gate: cello album
Oogst
OGRE Expert User
OGRE Expert User
Posts: 1067
Joined: Mon Mar 29, 2004 8:49 pm
Location: the Netherlands
x 43

Re: Cannot create D3D9 pixel shader from microcode

Post by Oogst »

Okay, one user has tried it already and unrolling the loop doesn't work.

I am thinking about turning off the shader 3 shaders altogether when the user has an Ati X1 card. What would be the best way to do that in Ogre? The crash happens pretty early, so I cannot just let Ogre load and then disable afterwards.
My dev blog
Awesomenauts: platforming MOBA (PC/Mac/Linux/XBox360/X1/PS3/PS4)
Blightbound: coop online dungeon crawler (PC)
Swords & Soldiers: side-scrolling RTS (Switch/PS3/Wii/PC/Mac/Linux/iPhone/iPad/Android)
Proun: abstract racing game (PC)
Cello Fortress: mixing game and live cello performance
The Ageless Gate: cello album
tommytom
Gnoblar
Posts: 8
Joined: Sun Jun 26, 2011 4:38 am
x 1

Re: Cannot create D3D9 pixel shader from microcode

Post by tommytom »

Jabberwocky wrote:Nicely done tommytom,
I hope I have players as helpful as you once my game is finished.
Heh. Not even a player yet. Just a fellow (amateur) developer and (indie) game enthusiast.
HOPING to be a player, soon.
Jabberwocky wrote:I'd also be curious how much VRAM tommytom's card has. Oogst, with that info, maybe you can make some guesses if VRAM is the problem, based on how much VRAM you guess Proun might need. You may need to add/update the minimum specs for Proun, or consider adding some sort of texture quality setting.

-- although looking at tommytom's full log, it doesn't look like that much stuff has been loaded yet, so maybe VRAM isn't the culprit.
If you haven't already, it's worth trying the ol' "update your video card drivers" solution.
Oogst wrote:@tommytom: how much video memory do you have and how you tried yo update your drivers?
128mb VRAM. Drivers are "Legacy" it will never be updated again. So, I have the latest possible. =(
Pretty sure it's not the VRAM myself, but just a hunch. I'm guessing it is what the other guy said with improper support for SM3. I think I tried another SM3 game or two (Attack of the 50ft Robot?) and it also failed, even though I think I had everything else matched.

The easiest fix, I would think, is to allow for a SM selector. I would rather just pick SM2 manually if I have to. Obviously, you will probably want to detect improper/incompatible cards and downgrade automatically though.

Hmm... I have 10-2_legacy_vista32-64_dd_ccc.exe here, so it matches the current: http://support.amd.com/us/gpudownload/w ... ng=English
If I read it correctly, they only update for critical fixes, but they do not mention limiting Windows 7; so I should still get updates for my card, but I haven't seen Feb 2011.

This is just a donor card. I don't have the funds to upgrade this machine, but the graphics card is the first thing on the list to upgrade when I do have the funds.
Oogst
OGRE Expert User
OGRE Expert User
Posts: 1067
Joined: Mon Mar 29, 2004 8:49 pm
Location: the Netherlands
x 43

Re: Cannot create D3D9 pixel shader from microcode

Post by Oogst »

@tommytom: have you already tried forcing graphics quality to Very low outside the game? You can open the file "Data/CurrentSettings.dat" in Notepad and set graphics quality to "Very low". Do you still get the same error then? The game shouldn't use anything but shader model 1 then, so I am wondering whether it will start, or will still try to load certain stuff then.
My dev blog
Awesomenauts: platforming MOBA (PC/Mac/Linux/XBox360/X1/PS3/PS4)
Blightbound: coop online dungeon crawler (PC)
Swords & Soldiers: side-scrolling RTS (Switch/PS3/Wii/PC/Mac/Linux/iPhone/iPad/Android)
Proun: abstract racing game (PC)
Cello Fortress: mixing game and live cello performance
The Ageless Gate: cello album
tommytom
Gnoblar
Posts: 8
Joined: Sun Jun 26, 2011 4:38 am
x 1

Re: Cannot create D3D9 pixel shader from microcode

Post by tommytom »

Oogst wrote:@tommytom: have you already tried forcing graphics quality to Very low outside the game? You can open the file "Data/CurrentSettings.dat" in Notepad and set graphics quality to "Very low". Do you still get the same error then? The game shouldn't use anything but shader model 1 then, so I am wondering whether it will start, or will still try to load certain stuff then.
Same error.
The .cf file from the other forum did nothing as well (same error).
=/
tommytom
Gnoblar
Posts: 8
Joined: Sun Jun 26, 2011 4:38 am
x 1

Re: Cannot create D3D9 pixel shader from microcode

Post by tommytom »

They have found a temporary solution here: http://www.ronimo-games.com/forum/viewt ... 51db#p4093

I changed the 64 to 50 and it got a new error (128 instead). I then changed 128 to 50 as well and it worked fine (finished a whole race).
Hopefully, that should help you discover the bug or a workaround.
Oogst
OGRE Expert User
OGRE Expert User
Posts: 1067
Joined: Mon Mar 29, 2004 8:49 pm
Location: the Netherlands
x 43

Re: Cannot create D3D9 pixel shader from microcode

Post by Oogst »

Hah, a couple of users found a solution, how awesome! 8)

I think I am just going to make an option in the startup menu to turn on "Ati compatability mode" or something like that. This will simply overwrite these shader files with the lame 50 sample versions.

This also means that the cause is indeed that these cards have a shader count limitation!
My dev blog
Awesomenauts: platforming MOBA (PC/Mac/Linux/XBox360/X1/PS3/PS4)
Blightbound: coop online dungeon crawler (PC)
Swords & Soldiers: side-scrolling RTS (Switch/PS3/Wii/PC/Mac/Linux/iPhone/iPad/Android)
Proun: abstract racing game (PC)
Cello Fortress: mixing game and live cello performance
The Ageless Gate: cello album
User avatar
Brocan
Orc
Posts: 441
Joined: Tue Aug 01, 2006 1:43 am
Location: Spain!!
x 8

Re: Cannot create D3D9 pixel shader from microcode

Post by Brocan »

Oogst wrote:Hah, a couple of users found a solution, how awesome! 8)

I think I am just going to make an option in the startup menu to turn on "Ati compatability mode" or something like that. This will simply overwrite these shader files with the lame 50 sample versions.

This also means that the cause is indeed that these cards have a shader count limitation!
Maybe you can write the 50 sample versions and force to execute the 50 samples technique using gpu rules? http://www.ogre3d.org/docs/manual/manua ... endor_rule
User avatar
dark_sylinc
OGRE Team Member
OGRE Team Member
Posts: 5509
Joined: Sat Jul 21, 2007 4:55 pm
Location: Buenos Aires, Argentina
x 1378

Re: Cannot create D3D9 pixel shader from microcode

Post by dark_sylinc »

Oogst wrote:Nvidia drivers indeed expand the loop. I looked at the assembly a while ago and it was indeed an expanded loop.
Nope. Cg expands the loop. Doing it manually won't help either, since it's the AMD drivers that detect the situation and convert hundreds of lines into a loop (as they detect each line is exactly the same but using a different constant register)
Oogst wrote: According to documentation, tex2dlod is only supported from sm4.0 and up, so I cannot use that solution. Source: http://http.developer.nvidia.com/Cg/tex2Dlod.html
Nope. It's SM 3.0 "fp40" is for OpenGL targets (NVIDIA only), and is a very similar implementation to that of SM 3.0; not 4.0
Oogst wrote: isn't that still a call to tex2d inside a for-loop, wasn't that the problem?
Calling tex2d with manually provided derivatives inside the loop is fine (it translates to a different instruction). The real problem is that when you don't provide them, the standard tex2D uses a different instruction that calculates them automatically; and derivatives can't be done inside conditional execution (theoretically, it should be fine in a loop with a constant number execution count, but practice says otherwise)
Oogst wrote: The vertex shader is indeed also Shader model 3. Mixing up models is totally okay on Nvidia cards, by the way, but I already knew it doesn't work on Ati cards, so I checked that
"It just works" in Nvidia cards. If you start using Windows Vista and mix SM 2.0 with SM 3.0; a few shaders will blow an nvidia card too.
Oogst wrote:However, the microcode thing is during compiling, right? Isn't this before Ogre combines these shaders for an actual render call? Anyway, here is the vertex shader definition and code:
This is what happens:
  1. Ogre loads source file in memory
  2. Cg compiles this source from memory into assembly (aka "microcode")
  3. Ogre sends microcode to Direct3D9
  4. Direct3D9 may perform a few tweaks, consistency checks, and minimal optimizations; and sends it into the driver.
  5. The driver performs extreme optimizations and checks (and sometimes, hacks) then translates it into trade-secret machine code the GPU can execute (which may be unique to that gpu model, unlike the x86 where an AMD Athlon can execute what a Phenom does, and what an Intel Core 2 does too)
  6. The driver schedules all GPUs resource and prepares it to run the machine code application
The place where you get failure means that either Direct3D9 encountered an error or the driver did. Judging from the amount of useful information (none), the driver did.
My bet the driver is converting the expanded code into a loop, without realizing it can't.

I strongly recommend anyone here with an ATI X1000 series card that has access to this game to enable the DX Debug runtimes which may throw additional information (if you don't have it, Google dx control panel.cpl and use it. It's an old app, but it does the job)

The vertex shader seems fine.

As for forbidding the material, there's a vendorID rule in the manual (the link has already been provided) for material techniques. Or you can use a ResourceLoader listener.

Cheers
Dark Sylinc

Edit: Changing it from Cg to HLSL does help in anything?

Edit 2: I did a terrible mistake!!! Loops can't be made even by the ATI driver in PS 3.0 because you're indexing constant registers (which isn't allowed in that SM 3.0!) I also just read in Wikipedia PS 3.0 has a minimum guaranteed instruction slot of 512. At 64 taps, you just need 8 instructions per tap to reach that limit. It's very likely the X1000 has only the minimum; and hence it fails. Ironically the solution would be to convert the assembly into an actual (non expanded) loop; but that cannot be done. The only solution is to lower the number of taps. Or put the tap weights into a texture and perform a loop without indexing constant registers (really nasty and isn't worth the effort)
tommytom
Gnoblar
Posts: 8
Joined: Sun Jun 26, 2011 4:38 am
x 1

Re: Cannot create D3D9 pixel shader from microcode

Post by tommytom »

dark_sylinc wrote:The place where you get failure means that either Direct3D9 encountered an error or the driver did. Judging from the amount of useful information (none), the driver did.
My bet the driver is converting the expanded code into a loop, without realizing it can't.

I strongly recommend anyone here with an ATI X1000 series card that has access to this game to enable the DX Debug runtimes which may throw additional information (if you don't have it, Google dx control panel.cpl and use it. It's an old app, but it does the job)
I would love to help, but I am stuck here:
Image

Almost everything is disabled even though it has been run as admin (UAC requests it).
You would need to talk me through what I need to do and how to resolve the above problem.

Edit:
BTW, I got the control panel from here: http://www.3dcenter.org/download/directx-control-panel
tommytom
Gnoblar
Posts: 8
Joined: Sun Jun 26, 2011 4:38 am
x 1

Re: Cannot create D3D9 pixel shader from microcode [SOLVED]

Post by tommytom »

I have installed the DirectX SDK http://www.microsoft.com/download/en/de ... en&id=6812
This solves the disabled options problem.

I need guidance from here as to figure out where it's logging to, etc.

Edit:
I used dbgview as that external link suggested and turned the debugging options all up.

This is all I get:

Code: Select all

00000000	0.00000000	[6092] irrKlang 3D Sound Engine version 1.1.3
00000001	0.03240085	[6092] Using DirectSound8 driver
00000002	1.01532972	[6092] No streaming was specified, but forcing to play sound streamed (See ISoundSource::setForcedStreamingThreshold): Sound/cr6idleW.ogg
00000003	1.02741051	[6092] No streaming was specified, but forcing to play sound streamed (See ISoundSource::setForcedStreamingThreshold): Sound/cr6boostW.ogg
00000004	1.03788066	[6092] No streaming was specified, but forcing to play sound streamed (See ISoundSource::setForcedStreamingThreshold): Sound/cr6medW.ogg
00000005	1.04843163	[6092] No streaming was specified, but forcing to play sound streamed (See ISoundSource::setForcedStreamingThreshold): Sound/cr6fastW.ogg
Edit2:
Maybe this will be helpful. Let me know if you need more info from this program:
Image
User avatar
dark_sylinc
OGRE Team Member
OGRE Team Member
Posts: 5509
Joined: Sat Jul 21, 2007 4:55 pm
Location: Buenos Aires, Argentina
x 1378

Re: Cannot create D3D9 pixel shader from microcode [SOLVED]

Post by dark_sylinc »

Usually you would see a different message coming from the application (specially it you tick "break on D3D9 errors" & "Maximum Validation") followed by a forced crash.
The only tab you would need to mess with is the Direct3D9 tab. The other ones (Audio, DirectDraw, etc) leave them in Retail to avoid adding garbage info.

Although the 512 instruction slot is speaking for itself. Mine (GeForce 8600 GTS) is set at 4096.
512 is dangerously low. That's probably it.

One would think PS 3.0 has a higher instruction count. Well, it kinda does, the limit is often said 65535 because that's when you perform a loop iteration; the instructions are the same, but they can be executed multiple times. Besides 512 is the minimum not the higher limit.

It's sad though, there's a video card implementing the bare minimum. I'll repeat, the X1000 are crap, they don't even support VTF when they should (off topic, strictly speaking, there was a loophole in the specification, as the vendor was forced to support VTF, but it was up to the vendor which texture formats were supported, and ATI chose to support none. So they do support VTF... they just don't provide any format available)