Skip to main content
Inspiring
September 16, 2016
Solved

ovr_CreateTextureSwapChainDX Fails with code -1004

  • September 16, 2016
  • 2 replies
  • 1385 views
I'm not sure what's going on.  My engine worked flawlessly for a long time.  Then all of a sudden it won't initialize the Rift.  It fails on ovr_CreateTextureSwapChainDX with -1004 (ovrError_NotInitialized).  However, I previously called ovr_Initialize and ovr_Create which both succeeded.  I also passed a swap chain structure and device to ovr_CreateTextureSwapChainDX.  I'm using DX11.  Here's some code to show what I'm passing:
texture_swap_chain_desc.Type = ovrTexture_2D;

texture_swap_chain_desc.ArraySize = 1;

texture_swap_chain_desc.Format = OVR_FORMAT_R8G8B8A8_UNORM_SRGB;

texture_swap_chain_desc.Width = buffer_size.w;

texture_swap_chain_desc.Height = buffer_size.h;

texture_swap_chain_desc.MipLevels = 1;

texture_swap_chain_desc.SampleCount = 1;

texture_swap_chain_desc.StaticImage = ovrFalse;

texture_swap_chain_desc.MiscFlags = ovrTextureMisc_DX_Typeless;

texture_swap_chain_desc.BindFlags = ovrTextureBind_DX_RenderTarget;

I've inspected the buffer_size, and it appears to hold valid values.  I'm also using a DK2, but that's not been an issue.  3rd party applications run fine, so this seems to just be my program.

Forgot to mention, I'm also using the latest SDK 1.8.0 now.
Best answer by djpeterson83
Ok, figured it out.  I've got calls crossing DLLs.  Because of this, the memory wasn't initialized in a single place.  Make sure all of your ovr_ calls are called in a single DLL or EXE, otherwise this will happen.  I'm still fighting issues, but they might still be related to this code migration, so I'll keep plugging away.

UPDATE: 
Yep, that fixed it.  For those of you who spread your calls across multiple modules, you might want to centralize everything to a single class and store function pointers to each ovr_* function you will call outside of your initialization module.  You can populate these function pointers after your call to ovr_Initialize succeeds.  Here's an example:

OculusVr::OculusVr() {
auto result = ::ovr_Initialize(nullptr);
if (OVR_FAILURE(result))
return;

// Save function pointers in here //
if (!init_library()) {
ovr_Shutdown();
return;
}

if (OVR_FAILURE(ovr_Create(&session, &luid_handle))) {
ovr_Shutdown();
return;
}
}

bool OculusVr::init_library() {
bool validity = true;

validity &= (this->ovr_Initialize = &::ovr_Initialize) != nullptr;
validity &= (this->ovr_Shutdown = &::ovr_Shutdown) != nullptr;
validity &= (this->ovr_GetLastErrorInfo = &::ovr_GetLastErrorInfo) != nullptr;
validity &= (this->ovr_GetVersionString = &::ovr_GetVersionString) != nullptr;
validity &= (this->ovr_TraceMessage = &::ovr_TraceMessage) != nullptr;
validity &= (this->ovr_IdentifyClient = &::ovr_IdentifyClient) != nullptr;
validity &= (this->ovr_GetHmdDesc = &::ovr_GetHmdDesc) != nullptr;
validity &= (this->ovr_GetTrackerCount = &::ovr_GetTrackerCount) != nullptr;
validity &= (this->ovr_GetTrackerDesc = &::ovr_GetTrackerDesc) != nullptr;
validity &= (this->ovr_Create = &::ovr_Create) != nullptr;
validity &= (this->ovr_Destroy = &::ovr_Destroy) != nullptr;
// ...
}

Now you can pass your OculusVr instance around and call ovr_* calls from it instead of the global ovr_* functions.   The OculusVr calls will point to the correct address space so that your code calls the correct functions.

FYI: Please fix this ridiculous editor.  I have no idea if my post is even saved.  It seems to be all manners of broken, and I've had to format the above post 5 times now.

2 replies

djpeterson83AuthorAnswer
Inspiring
September 17, 2016
Ok, figured it out.  I've got calls crossing DLLs.  Because of this, the memory wasn't initialized in a single place.  Make sure all of your ovr_ calls are called in a single DLL or EXE, otherwise this will happen.  I'm still fighting issues, but they might still be related to this code migration, so I'll keep plugging away.

UPDATE: 
Yep, that fixed it.  For those of you who spread your calls across multiple modules, you might want to centralize everything to a single class and store function pointers to each ovr_* function you will call outside of your initialization module.  You can populate these function pointers after your call to ovr_Initialize succeeds.  Here's an example:

OculusVr::OculusVr() {
auto result = ::ovr_Initialize(nullptr);
if (OVR_FAILURE(result))
return;

// Save function pointers in here //
if (!init_library()) {
ovr_Shutdown();
return;
}

if (OVR_FAILURE(ovr_Create(&session, &luid_handle))) {
ovr_Shutdown();
return;
}
}

bool OculusVr::init_library() {
bool validity = true;

validity &= (this->ovr_Initialize = &::ovr_Initialize) != nullptr;
validity &= (this->ovr_Shutdown = &::ovr_Shutdown) != nullptr;
validity &= (this->ovr_GetLastErrorInfo = &::ovr_GetLastErrorInfo) != nullptr;
validity &= (this->ovr_GetVersionString = &::ovr_GetVersionString) != nullptr;
validity &= (this->ovr_TraceMessage = &::ovr_TraceMessage) != nullptr;
validity &= (this->ovr_IdentifyClient = &::ovr_IdentifyClient) != nullptr;
validity &= (this->ovr_GetHmdDesc = &::ovr_GetHmdDesc) != nullptr;
validity &= (this->ovr_GetTrackerCount = &::ovr_GetTrackerCount) != nullptr;
validity &= (this->ovr_GetTrackerDesc = &::ovr_GetTrackerDesc) != nullptr;
validity &= (this->ovr_Create = &::ovr_Create) != nullptr;
validity &= (this->ovr_Destroy = &::ovr_Destroy) != nullptr;
// ...
}

Now you can pass your OculusVr instance around and call ovr_* calls from it instead of the global ovr_* functions.   The OculusVr calls will point to the correct address space so that your code calls the correct functions.

FYI: Please fix this ridiculous editor.  I have no idea if my post is even saved.  It seems to be all manners of broken, and I've had to format the above post 5 times now.
Inspiring
September 19, 2016
Ok, figured it out.  I've got calls crossing DLLs.  Because of this, the memory wasn't initialized in a single place.  Make sure all of your ovr_ calls are called in a single DLL or EXE, otherwise this will happen.  I'm still fighting issues, but they might still be related to this code migration, so I'll keep plugging away.

UPDATE: 
Yep, that fixed it.  For those of you who spread your calls across multiple modules, you might want to centralize everything to a single class and store function pointers to each ovr_* function you will call outside of your initialization module.  You can populate these function pointers after your call to ovr_Initialize succeeds.  Here's an example:

OculusVr::OculusVr() {
auto result = ::ovr_Initialize(nullptr);
if (OVR_FAILURE(result))
return;

// Save function pointers in here //
if (!init_library()) {
ovr_Shutdown();
return;
}

if (OVR_FAILURE(ovr_Create(&session, &luid_handle))) {
ovr_Shutdown();
return;
}
}

bool OculusVr::init_library() {
bool validity = true;

validity &= (this->ovr_Initialize = &::ovr_Initialize) != nullptr;
validity &= (this->ovr_Shutdown = &::ovr_Shutdown) != nullptr;
validity &= (this->ovr_GetLastErrorInfo = &::ovr_GetLastErrorInfo) != nullptr;
validity &= (this->ovr_GetVersionString = &::ovr_GetVersionString) != nullptr;
validity &= (this->ovr_TraceMessage = &::ovr_TraceMessage) != nullptr;
validity &= (this->ovr_IdentifyClient = &::ovr_IdentifyClient) != nullptr;
validity &= (this->ovr_GetHmdDesc = &::ovr_GetHmdDesc) != nullptr;
validity &= (this->ovr_GetTrackerCount = &::ovr_GetTrackerCount) != nullptr;
validity &= (this->ovr_GetTrackerDesc = &::ovr_GetTrackerDesc) != nullptr;
validity &= (this->ovr_Create = &::ovr_Create) != nullptr;
validity &= (this->ovr_Destroy = &::ovr_Destroy) != nullptr;
// ...
}

Now you can pass your OculusVr instance around and call ovr_* calls from it instead of the global ovr_* functions.   The OculusVr calls will point to the correct address space so that your code calls the correct functions.