Not properly falling back to supported techniques?

Walley

15-04-2007 04:20:39

I'm having an issue where instead of falling back to a supported technique on older hardware, PLSM is simply spitting an error about nothing being supported:


02:22:38: OGRE EXCEPTION(2:InvalidParametersException): Cannot find a TextureMode supported by current hardware! (shaders/num texture units...) in getNextTextureFormat at ..\src\OgrePagingLandScapeTextureManager.cpp (line 153)


The older hardware only support 8 texture units for pixel shaders. However, there are definitely techniques in the material that are supported in said situation.
The material has four techniques, with two of them requiring a card supporting 16 texture units, and two requiring 8. They are on separate lod_indexes, but making these the same has no impact. However, if I remove the high end techniques everything works OK on the machine with only 8 texture units.

The material is as follows (quite long sorry ;))


material PLSM/SplattingShaderDecompress
{
// LIGHTING + SPECULAR
technique LightingSpecular
{
lod_index 0

pass AmbientPass
{
ambient 1 1 1
emissive 0 0 0
diffuse 0 0 0
specular 0 0 0 0

vertex_program_ref PLSM/Splatting_Decompress_VP
{
param_named splatScale float 50
param_named sunDir float3 -0.7678 0.1939 0.6107
param_named specNormalFactor float 0.25
}

fragment_program_ref PLSM/Splatting_Specular_FP
{
param_named specularPower float 32
param_named specularScale float 0.5
param_named specularColour float4 1.0 0.5 0.0 1.0
}

shadow_receiver_vertex_program_ref PLSM/ShadowReceiver_Decompress_VP
{
}

texture_unit
{
texture Base
}
texture_unit
{
texture Light
}
texture_unit
{
texture Coverage
}
texture_unit
{
texture Alpha
}

texture_unit
{
texture Splatting
}
texture_unit
{
texture Splatting
}
texture_unit
{
texture Splatting
}
texture_unit
{
texture Splatting
}

texture_unit
{
texture normal_sand.dds
}
texture_unit
{
texture normal_grass.dds
}
texture_unit
{
texture normal_rock.dds
}
texture_unit
{
texture normal_snow.dds
}
}

pass LightingPass
{
iteration once_per_light

ambient 0 0 0
emissive 0 0 0
diffuse 1 1 1
specular 1 1 1 1

fog_override true none

scene_blend add

vertex_program_ref PLSM/SplattingLighting_Decompress_VP
{
param_named splatScale float 50
}

fragment_program_ref PLSM/SplattingLighting_FP
{
}

shadow_receiver_vertex_program_ref PLSM/ShadowReceiver_Decompress_VP
{
}

texture_unit
{
texture Coverage
}

texture_unit
{
texture Splatting
}
texture_unit
{
texture Splatting
}
texture_unit
{
texture Splatting
}
texture_unit
{
texture Splatting
}

texture_unit
{
cubic_texture normalize.png combinedUVW
tex_coord_set 1
tex_address_mode clamp
}
}
}


// LIGHTING
technique Lighting
{
lod_index 1

pass AmbientPass
{
ambient 1 1 1
emissive 0 0 0
diffuse 0 0 0
specular 0 0 0 0

vertex_program_ref PLSM/Splatting_Decompress_VP
{
param_named splatScale float 200
}

fragment_program_ref PLSM/Splatting_Plain_FP
{
}

shadow_receiver_vertex_program_ref PLSM/ShadowReceiver_Decompress_VP
{
}

texture_unit
{
texture Base
}
texture_unit
{
texture Light
}
texture_unit
{
texture Coverage
}

texture_unit
{
texture Splatting
}
texture_unit
{
texture Splatting
}
texture_unit
{
texture Splatting
}
texture_unit
{
texture Splatting
}
}

pass LightingPass
{
iteration once_per_light

ambient 0 0 0
emissive 0 0 0
diffuse 1 1 1
specular 1 1 1 1

fog_override true none

scene_blend add

vertex_program_ref PLSM/SplattingLighting_Decompress_VP
{
param_named splatScale float 200
}

fragment_program_ref PLSM/SplattingLighting_FP
{
}

shadow_receiver_vertex_program_ref PLSM/ShadowReceiver_Decompress_VP
{
}

texture_unit
{
texture Coverage
}

texture_unit
{
texture Splatting
}
texture_unit
{
texture Splatting
}
texture_unit
{
texture Splatting
}
texture_unit
{
texture Splatting
}

texture_unit
{
cubic_texture normalize.png combinedUVW
tex_coord_set 1
tex_address_mode clamp
}
}
}


// SPECULAR
technique Specular
{
lod_index 2

pass AmbientPass
{
ambient 1 1 1
emissive 0 0 0
diffuse 0 0 0
specular 0 0 0 0

vertex_program_ref PLSM/Splatting_Decompress_VP
{
param_named splatScale float 200
param_named sunDir float3 -0.7678 0.1939 0.6107
param_named specNormalFactor float 0.5
}

fragment_program_ref PLSM/Splatting_Specular_FP
{
param_named specularSpreadPower float 32
param_named specularPower float 16
param_named specularScale float 1.0
param_named specularColour float4 1.0 0.5 0.0 1.0
}

shadow_receiver_vertex_program_ref PLSM/ShadowReceiver_Decompress_VP
{
}

texture_unit
{
texture Base
}
texture_unit
{
texture Light
}
texture_unit
{
texture Coverage
}
texture_unit
{
texture Alpha
}

texture_unit
{
texture Splatting
}
texture_unit
{
texture Splatting
}
texture_unit
{
texture Splatting
}
texture_unit
{
texture Splatting
}

texture_unit
{
texture normal_sand.dds
}
texture_unit
{
texture normal_grass.dds
}
texture_unit
{
texture normal_rock.dds
}
texture_unit
{
texture normal_snow.dds
}
}
}


// PLAIN
technique Plain
{
lod_index 3

pass AmbientPass
{
ambient 1 1 1
emissive 0 0 0
diffuse 0 0 0
specular 0 0 0 0

vertex_program_ref PLSM/Splatting_Decompress_VP
{
param_named splatScale float 200
}

fragment_program_ref PLSM/Splatting_Plain_FP
{
}

shadow_receiver_vertex_program_ref PLSM/ShadowReceiver_Decompress_VP
{
}

texture_unit
{
texture Base
}
texture_unit
{
texture Light
}
texture_unit
{
texture Coverage
}

texture_unit
{
texture Splatting
}
texture_unit
{
texture Splatting
}
texture_unit
{
texture Splatting
}
texture_unit
{
texture Splatting
}
}
}


// DEPTH
technique Depth
{
scheme Depth

pass
{
fog_override true none

vertex_program_ref DecompressDepthEncode_VP
{
}

fragment_program_ref DepthEncode_FP
{
}

shadow_receiver_vertex_program_ref PLSM/ShadowReceiver_Decompress_VP
{
}

texture_unit
{
texture redgreenramp.png
tex_address_mode wrap
filtering none
}
}
}
}


If I leave only the // PLAIN technique it runs fine.

With some observation, I believe the culprit is in PagingLandScapeTexture::isMaterialSupported:


foreach (technique) {
foreach (pass) {
if(passNumTextureUnits > numTextureUnits)
numTextureUnits = passNumTextureUnits;
}
}

...

if (opt->numTextureUnits < numTextureUnits)
return false;


It's rejecting the material based on the most texture unit used in the whole material, whereas it should be using the most texture units from the technique with the least texture units, if that makes sense ;). I'll try changing it and post what works :).

Walley

15-04-2007 04:41:04

Fixed the problem :), here's the modified function:
http://rafb.net/p/shnuOx12.html

Lines which have been changed or added are marked with a ** to the left.
I'd submit a patch but I haven't properly got CVS setup and I'm rather busy :<.