• Announcements

    • khawk

      Download the Game Design and Indie Game Marketing Freebook   07/19/17

      GameDev.net and CRC Press have teamed up to bring a free ebook of content curated from top titles published by CRC Press. The freebook, Practices of Game Design & Indie Game Marketing, includes chapters from The Art of Game Design: A Book of Lenses, A Practical Guide to Indie Game Marketing, and An Architectural Approach to Level Design. The GameDev.net FreeBook is relevant to game designers, developers, and those interested in learning more about the challenges in game development. We know game development can be a tough discipline and business, so we picked several chapters from CRC Press titles that we thought would be of interest to you, the GameDev.net audience, in your journey to design, develop, and market your next game. The free ebook is available through CRC Press by clicking here. The Curated Books The Art of Game Design: A Book of Lenses, Second Edition, by Jesse Schell Presents 100+ sets of questions, or different lenses, for viewing a game’s design, encompassing diverse fields such as psychology, architecture, music, film, software engineering, theme park design, mathematics, anthropology, and more. Written by one of the world's top game designers, this book describes the deepest and most fundamental principles of game design, demonstrating how tactics used in board, card, and athletic games also work in video games. It provides practical instruction on creating world-class games that will be played again and again. View it here. A Practical Guide to Indie Game Marketing, by Joel Dreskin Marketing is an essential but too frequently overlooked or minimized component of the release plan for indie games. A Practical Guide to Indie Game Marketing provides you with the tools needed to build visibility and sell your indie games. With special focus on those developers with small budgets and limited staff and resources, this book is packed with tangible recommendations and techniques that you can put to use immediately. As a seasoned professional of the indie game arena, author Joel Dreskin gives you insight into practical, real-world experiences of marketing numerous successful games and also provides stories of the failures. View it here. An Architectural Approach to Level Design This is one of the first books to integrate architectural and spatial design theory with the field of level design. The book presents architectural techniques and theories for level designers to use in their own work. It connects architecture and level design in different ways that address the practical elements of how designers construct space and the experiential elements of how and why humans interact with this space. Throughout the text, readers learn skills for spatial layout, evoking emotion through gamespaces, and creating better levels through architectural theory. View it here. Learn more and download the ebook by clicking here. Did you know? GameDev.net and CRC Press also recently teamed up to bring GDNet+ Members up to a 20% discount on all CRC Press books. Learn more about this and other benefits here.
Sign in to follow this  
Followers 0
Alex Hrin

DirectX - invalid device. Why ?

6 posts in this topic

Hi all! I'm writing a short game editor type application and I stumbled upon a wierd phenomenon. When loading a model from an .x file I wanted to compute it's bounding box and to my surprise the vertex buffer lock crashes my app every time. The error is:
Quote:
An unhandled exception of type 'System.AccessViolationException' occurred in RAW3D Editor.exe Additional information: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
The same happens when I try calling D3DXCreateBox(). I did some checking and found out that ValidateDevice() returns E_FAIL. Here's the code: R3DDevice.h:
#pragma once

#ifndef R3D_DEVICE_H
#define R3D_DEVICE_H

namespace RAW3DEditor
{
	namespace R3DDirect3D 
	{

		class R3DRenderDevice 
		{

		public:
			R3DRenderDevice();
			void Release();
			void ToggleRendering()		{RenderingEnabled = !RenderingEnabled;};
			void EnableRendering()		{RenderingEnabled = true;};
			void DisableRendering()		{RenderingEnabled = false;};
			bool GetRenderingEnabled()	{return RenderingEnabled;};

		protected:
			~R3DRenderDevice();
			void SetDeviceParameters(int Height, int Width);

		public:
			HRESULT Render();
			HRESULT SetViewport(D3DVIEWPORT9* NewViewport);
			HRESULT InitializeD3D(HWND ParentWindow, int Height, int Width);
			HRESULT SetBackBuffer(int Height, int Width);
			IDirect3DDevice9* GetDevice();
			IDirect3DSurface9* GetBackbuffer();

		private:
			IDirect3D9*             Direct3D;		  
			IDirect3DDevice9*       Direct3DDevice;  
			D3DPRESENT_PARAMETERS	D3DPresentParams; 
			HWND					Window;
			bool					RenderingEnabled;
			FILE*					log;
		};

	}
}

#endif

R3DDevice.cpp:
#include "stdafx.h"

using namespace RAW3DEditor::R3DDirect3D;

R3DRenderDevice::R3DRenderDevice()
{
	SYSTEMTIME LocalTime;
	Direct3D = NULL;
	Direct3DDevice = NULL;
	RenderingEnabled = false;
	_wfopen_s(&log, L"R3DRenderLog.log", L"w");
	GetLocalTime(&LocalTime);
	fwprintf_s(log, L"%02d.%02d.%04d %02d:%02d\n\n", LocalTime.wDay, LocalTime.wMonth, 
			LocalTime.wYear, LocalTime.wHour, LocalTime.wMinute);
	fwprintf_s(log, L"Basic device constructed.\n");
}

R3DRenderDevice::~R3DRenderDevice()
{
	if(Direct3D)
		Direct3D->Release();
	if(Direct3DDevice)
		Direct3DDevice->Release();
	fwprintf_s(log, L"Device shut down.\n");
	fclose(log);
}

HRESULT R3DRenderDevice::SetBackBuffer(int Height, int Width)
{
	HRESULT hr;
	SetDeviceParameters(Height, Width);
	if( SUCCEEDED( hr = Direct3DDevice->Reset(&D3DPresentParams) ) )
		fwprintf_s(log, L"Device successfuly reset for %d by %d.\n", Width, Height);
	else
		fwprintf_s(log, L"Device reset failed for %d by %d.\n", Width, Height);
	return D3D_OK;
}

void R3DRenderDevice::SetDeviceParameters(int Height, int Width)
{
	D3DFORMAT DetectedDepthFormat, DetectedBackBufferFormat;
	int StencilIndex, SurfaceIndex;
	BufferFormats* AvailableFormats = new BufferFormats();
	HRESULT hr;
	for(SurfaceIndex = AvailableFormats->LBackBufferFormats; SurfaceIndex >= 1; SurfaceIndex--)
		for(StencilIndex = AvailableFormats->LStencilBufferFormats; StencilIndex >= 1; StencilIndex--)
		{
			DetectedBackBufferFormat = AvailableFormats->BackBufferFormats[SurfaceIndex];
			DetectedDepthFormat = AvailableFormats->StencilBufferFormats[StencilIndex];
			if(SUCCEEDED(hr = Direct3D->CheckDeviceFormat( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, 
														   DetectedBackBufferFormat, 
														   D3DUSAGE_DEPTHSTENCIL, 
														   D3DRTYPE_SURFACE, DetectedDepthFormat) ) )
			{
				SurfaceIndex = 0;
				StencilIndex = 0;
			}
		}
	delete AvailableFormats;

	ZeroMemory(&D3DPresentParams, sizeof D3DPRESENT_PARAMETERS);
	D3DPresentParams.BackBufferHeight = Height;
	D3DPresentParams.BackBufferWidth = Width;
    D3DPresentParams.Windowed = TRUE;
	D3DPresentParams.AutoDepthStencilFormat = DetectedDepthFormat;
	D3DPresentParams.EnableAutoDepthStencil = TRUE;
    D3DPresentParams.SwapEffect = D3DSWAPEFFECT_DISCARD;
	D3DPresentParams.MultiSampleType = D3DMULTISAMPLE_NONE;
	D3DPresentParams.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT;
	D3DPresentParams.BackBufferFormat = DetectedBackBufferFormat;
}

HRESULT R3DRenderDevice::InitializeD3D(HWND ParentWindow, int Height, int Width)
{
	HRESULT hr;
	Window = ParentWindow;
    if( NULL == ( Direct3D = Direct3DCreate9( D3D_SDK_VERSION ) ) )
	{
		fwprintf_s(log, L"Direct3D object creation failed.\n");
        return E_FAIL;
	}

	SetDeviceParameters(Height, Width);

    if( FAILED( Direct3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, Window,
										D3DCREATE_HARDWARE_VERTEXPROCESSING,
										&D3DPresentParams, &Direct3DDevice ) ) )
	{
		fwprintf_s(log, L"Direct3D device creation failed.\n");
        return E_FAIL;
	}

	if( FAILED( hr = Direct3DDevice->ValidateDevice(NULL) ) )
		DXTRACE_ERR( L"Device validation failed", hr );

	fprintf_s(log, "Device initialized.\n");
    return D3D_OK;
}
HRESULT R3DRenderDevice::Render()
{
	if( !Direct3DDevice )
    {
		fwprintf_s(log, L"Scene rendering failed. Device not initialized or invalid.\n");
		return E_FAIL;
	}

	Direct3DDevice->Clear( 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(255, 255, 255), 1.0f, 0 );
    
    if( SUCCEEDED( Direct3DDevice->BeginScene() ) )
    {

        Direct3DDevice->EndScene();
    }
	else
	{
		fwprintf_s(log, L"Scene rendering failed.\n");
		return E_FAIL;
	}

    Direct3DDevice->Present( NULL, NULL, NULL, NULL );
	return D3D_OK;
}

HRESULT R3DRenderDevice::SetViewport(D3DVIEWPORT9 *NewViewport)
{
	if ( FAILED( Direct3DDevice->SetViewport(NewViewport) ) )
	{
		fwprintf_s(log, L"New viewport has been set successfully\n");
		return E_FAIL;
	}
	return D3D_OK;
}

IDirect3DDevice9* R3DRenderDevice::GetDevice()
{
	return this->Direct3DDevice;
}

IDirect3DSurface9* R3DRenderDevice::GetBackbuffer()
{
	IDirect3DSurface9* Backbuffer;
	HRESULT hr = this->Direct3DDevice->GetBackBuffer( 0, 0, D3DBACKBUFFER_TYPE_MONO, &Backbuffer );
	if(SUCCEEDED(hr))
		fwprintf_s(log, L"Backbuffer surface retrieved successfuly.\n");
	else
		fwprintf_s(log, L"Backbuffer surface could not be retrieved.\n");
	return Backbuffer;
}

void R3DRenderDevice::Release()
{
	this->~R3DRenderDevice();
}

The code that requests device creation is
this->Device = new R3DRenderDevice;
this->Device->InitializeD3D(ClientHWND, ClientHeight, ClientWidth);

Where ClientHWND is the window handle for a class derived form System::Windows::Forms::Panel and the other two parameters represent the size of the panel. The D3Dobject creation does not encounter any errors and neither does the device creation. I can also reset the device and even some basic drawing works too but when I try to validate the function returns E_FAIL and locking buffers or creating primitives gives the AccessViolationException at runtime. What's happening ?
0

Share this post


Link to post
Share on other sites

Quote:

Direct3D9: (WARN) :D3D Unsupported for the adapter format passed to CheckDeviceFormat
Direct3D9: (WARN) :D3D Unsupported for the adapter format passed to CheckDeviceFormat
Direct3D9: (WARN) :D3D Unsupported for the adapter format passed to CheckDeviceFormat
Direct3D9: (WARN) :D3D Unsupported for the adapter format passed to CheckDeviceFormat
Direct3D9: (WARN) :D3D Unsupported for the adapter format passed to CheckDeviceFormat
Direct3D9: (WARN) :D3D Unsupported for the adapter format passed to CheckDeviceFormat
Direct3D9: (WARN) :D3D Unsupported for the adapter format passed to CheckDeviceFormat
Direct3D9: (WARN) :D3D Unsupported for the adapter format passed to CheckDeviceFormat
Direct3D9: (WARN) :D3D Unsupported for the adapter format passed to CheckDeviceFormat
Direct3D9: (ERROR) :D3DFMT_UNKNOWN is not a valid format.
Direct3D9: (INFO) :======================= Hal HWVP device selected

Direct3D9: (INFO) :HalDevice Driver style b

Direct3D9: :BackBufferCount not specified, considered default 1
Direct3D9: :DoneExclusiveMode
Direct3D9: (INFO) :Using FF to VS converter

Direct3D9: (INFO) :Using FF to PS converter

D3D9 Helper: Warning: Default value for D3DRS_POINTSIZE_MAX is 2.19902e+012f, not 4.91616e-316f. This is ok.
Direct3D9: (ERROR) :Invalid vertex declaration.

D3D9 Helper: IDirect3DDevice9::ValidateDevice failed: E_FAIL
.\Sources\R3DDevice.cpp(94): Device validation failed hr=E_FAIL (0x80004005)
D3DX: Unicode support: 1


This is pretty weird. I have a procedure that checks for valid formats in R3DDevice.cpp and it seems to stop at D3DFMT_UNKNOWN. Invalid vertex declaration ? D3DRS_POINTSIZE_MAX ? Does it have something to do with D3DPRESENT_PARAMETERS ?
0

Share this post


Link to post
Share on other sites
Quote:
Original post by Alex Hrin

Quote:

Direct3D9: (WARN) :D3D Unsupported for the adapter format passed to CheckDeviceFormat
Direct3D9: (WARN) :D3D Unsupported for the adapter format passed to CheckDeviceFormat
Direct3D9: (WARN) :D3D Unsupported for the adapter format passed to CheckDeviceFormat
Direct3D9: (WARN) :D3D Unsupported for the adapter format passed to CheckDeviceFormat
Direct3D9: (WARN) :D3D Unsupported for the adapter format passed to CheckDeviceFormat
Direct3D9: (WARN) :D3D Unsupported for the adapter format passed to CheckDeviceFormat
Direct3D9: (WARN) :D3D Unsupported for the adapter format passed to CheckDeviceFormat
Direct3D9: (WARN) :D3D Unsupported for the adapter format passed to CheckDeviceFormat
Direct3D9: (WARN) :D3D Unsupported for the adapter format passed to CheckDeviceFormat
Direct3D9: (ERROR) :D3DFMT_UNKNOWN is not a valid format.
Direct3D9: (INFO) :======================= Hal HWVP device selected

Direct3D9: (INFO) :HalDevice Driver style b

Direct3D9: :BackBufferCount not specified, considered default 1
Direct3D9: :DoneExclusiveMode
Direct3D9: (INFO) :Using FF to VS converter

Direct3D9: (INFO) :Using FF to PS converter

D3D9 Helper: Warning: Default value for D3DRS_POINTSIZE_MAX is 2.19902e+012f, not 4.91616e-316f. This is ok.
Direct3D9: (ERROR) :Invalid vertex declaration.

D3D9 Helper: IDirect3DDevice9::ValidateDevice failed: E_FAIL
.\Sources\R3DDevice.cpp(94): Device validation failed hr=E_FAIL (0x80004005)
D3DX: Unicode support: 1


This is pretty weird. I have a procedure that checks for valid formats in R3DDevice.cpp and it seems to stop at D3DFMT_UNKNOWN. Invalid vertex declaration ? D3DRS_POINTSIZE_MAX ? Does it have something to do with D3DPRESENT_PARAMETERS ?
The unknown format error message means you're passing D3DFMT_UNKNOWN as a format somewhere. Double check everywhere you pass D3DFORMAT in and make sure it's not D3DFMT_UNKNOWN.

The invalid vertex declaration means that you haven't called IDirect3DDevice9::SetFVF() or IDirect3DDevice9::SetVertexDeclaration() with a valid value. That seems to be why ValidateDevice() is failing (As a guess).

The pointsize thing is nothing to worry about; I believe NVidia drivers set the default value of that to a different value than usual. You can just ignore it.
0

Share this post


Link to post
Share on other sites
It may not be the cause of your problem, but your format checking loop only checks for success. If your loop does not find a compatible format, you end up with whatever stencilindex=1 and surfaceindex=1 are, even if they're not compatible.
0

Share this post


Link to post
Share on other sites
I checked some other things around here and found what is maybe a deeper level of the problem. IDirect3DDevice9::SetFVF() or Direct3DDevice9::SetVertexDeclaration() are probably being called by D3DXLoadMeshFromX() when it tries to load the mesh but I checked for D3DFORMAT and D3DPRESENT_PARAMETERS should receive D3DFMT_D24S8 (75) for the DepthStencilFormat and D3DFMT_X8R8G8B8 (22) for the backbuffer format.
Those are the values the loop returns. In the image below it can clearly be seen that even after the execution of:


ZeroMemory(&D3DPresentParams, sizeof D3DPRESENT_PARAMETERS);
D3DPresentParams.BackBufferHeight = Height;
D3DPresentParams.BackBufferWidth = Width;
D3DPresentParams.Windowed = TRUE;
D3DPresentParams.AutoDepthStencilFormat = DetectedDepthFormat;



D3DPresentParams.AutoDepthStencilFormat is 585 (and I can't imagine why since this is the only time the code modifies it) even though it should take on DetectedDepthFormat's value (the watch on the lower left pretty much speaks for itself ). D3DPresentParams is not a pointer and this is the first portion of the code that uses it. It seems that it can't take on new values.

D3DPRESENT_PARAMETERS

Sorry for the stupid question but do I have to call IDirect3DDevice9::SetFVF() before validating the device ? I never did it before and it seemed to work fine until now.

About the loop only returning success: yes, I know it's incomplete but for now I only want it to work. I'm testing it on a ATI RadeonHD 2900XT and those structures (BackBufferFormats[] and StencilBufferFormats[]) hold all values listed in the SDK for backbuffers and stencil buffers so it has a very slim chance of not finding anything for now.
0

Share this post


Link to post
Share on other sites
Quote:
do I have to call IDirect3DDevice9::SetFVF() before validating the device ?

You shouldn't. In fact, it'd be difficult since you haven't created the device yet (I assume)! [smile]

EDIT: Also, D3DFMT_UNKNOWN has a value of 0, not 585. Somethings amiss.
0

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0