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
µcode,
&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");
}