Jump to content

  • Log In with Google      Sign In   
  • Create Account

Passing d3d device by reference


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
13 replies to this topic

#1 cozzie   Members   -  Reputation: 1777

Like
0Likes
Like

Posted 23 June 2013 - 01:44 PM

Hi,

Would there be any risk in passing a d3d device as a const reference to a function?

To be specific:

 

LPDIRECTDDEVICE9 myDev is basically a pointer: *IDIRECT3DDEVICE9

 

A function used the device for d3d functions as parameter, but doesn't alter the d3d device itself, thats why I think it should be possible.

It compiles and runs, but just curious if it's 'OK'.

 

Example:

 

bool CreateTextures(const LPDIRECTDDEVICE9 &pd3ddev)

{

   D3DXCreateTextureFromFile(......., pd3ddev);

}



Sponsor:

#2 SiCrane   Moderators   -  Reputation: 9676

Like
0Likes
Like

Posted 23 June 2013 - 01:46 PM

You can do it, but it's fairly pointless. If you're using raw pointers than you might as well pass by value. Using a const reference doesn't give you any benefit here.

#3 mhagain   Crossbones+   -  Reputation: 8285

Like
0Likes
Like

Posted 23 June 2013 - 04:44 PM

Passing a IDirect3DDevice9 as const should generally cause a compiler error as subsequent usage of that device won't match the signature in the d3d9.h header file.

 

As an example, a "CreateVertexShader" routine you might write that takes the device as a parameter won't compile if the device is passed as const, and will specifically fail on this line:

Device->CreateVertexShader (....

And with this error:

 

error C2662: 'IDirect3DDevice9::CreateVertexShader' : cannot convert 'this' pointer from 'const IDirect3DDevice9' to 'IDirect3DDevice9 &'

 

As an additional consideration, any well-written D3DX function that obeys the rules of COM will increment the reference count on the device (via AddRef) on entry and decrement it (via Release) on exit, so the D3DX function will modify the device.  Also, you can infer that any Device->Create call also increments the reference count on the device from the fact that the device will also leak if the created resource leaks.


It appears that the gentleman thought C++ was extremely difficult and he was overjoyed that the machine was absorbing it; he understood that good C++ is difficult but the best C++ is well-nigh unintelligible.


#4 SiCrane   Moderators   -  Reputation: 9676

Like
0Likes
Like

Posted 23 June 2013 - 04:57 PM

A const LPDIRECTDDEVICE9 & isn't a const IDirect3DDevice9 * &, it's a IDirect3DDevice9 * const &. The pointer is const, not what is pointed to.

#5 mhagain   Crossbones+   -  Reputation: 8285

Like
0Likes
Like

Posted 23 June 2013 - 05:00 PM

A const LPDIRECTDDEVICE9 & isn't a const IDirect3DDevice9 * &, it's a IDirect3DDevice9 * const &. The pointer is const, not what is pointed to.

 

True, my bad.

 

It still won't compile though.


It appears that the gentleman thought C++ was extremely difficult and he was overjoyed that the machine was absorbing it; he understood that good C++ is difficult but the best C++ is well-nigh unintelligible.


#6 SiCrane   Moderators   -  Reputation: 9676

Like
0Likes
Like

Posted 23 June 2013 - 05:13 PM

Are you sure about that? This compiles fine for me:
#include <d3d9.h>

void foo(const LPDIRECT3DDEVICE9 & ptr) {
  ptr->AddRef();
  ptr->CreateVertexShader(0, 0);
  ptr->Release();
}
Again, the pointer is const. What is pointer is pointing to isn't.

#7 mhagain   Crossbones+   -  Reputation: 8285

Like
0Likes
Like

Posted 23 June 2013 - 05:32 PM

Are you sure about that? This compiles fine for me:

#include <d3d9.h>

void foo(const LPDIRECT3DDEVICE9 & ptr) {
  ptr->AddRef();
  ptr->CreateVertexShader(0, 0);
  ptr->Release();
}
Again, the pointer is const. What is pointer is pointing to isn't.

 

 

Ah, OK.  I tested with "const IDirect3DDevice9 &" which does fail with the error I mentioned (as does "const IDirect3DDevice9 *").  It's not the constness that causes that failure, it's the signatures not matching.


Edited by mhagain, 23 June 2013 - 05:34 PM.

It appears that the gentleman thought C++ was extremely difficult and he was overjoyed that the machine was absorbing it; he understood that good C++ is difficult but the best C++ is well-nigh unintelligible.


#8 SiCrane   Moderators   -  Reputation: 9676

Like
0Likes
Like

Posted 23 June 2013 - 06:14 PM

No, that is the const causing the failure. When you have a const IDirect3DDevice9 *, the IDirect3DDevice9 object pointed to is const, so you can't call non-const member functions like CreateVertexShader(), AddRef() and Release().

#9 cozzie   Members   -  Reputation: 1777

Like
0Likes
Like

Posted 23 June 2013 - 06:20 PM

Ok, so what I'm basically doong is making the pointer const,cso it cant point anywhere else.
This basically doesn't do anything (needed).

Would I still be able to execute functions on the d3d device if I made the 'device' it points too, const?
( and how should I do that)

On the other hand, what would be the point if I can release the device etc. And do other things with it anyway.
In that case I can just pass the LPDIRECT3DDEVICE (which is a pointer allready) not being a reference, just by value (of the pointer). This works for sure, because I did that for 'ages', before my 'const implementation' all over my engine.

#10 cozzie   Members   -  Reputation: 1777

Like
0Likes
Like

Posted 23 June 2013 - 06:25 PM

Sorry, I'm a bit confused.

Say I wanted to pass the LPDIRECT3DDEVICE9 with the possibility to execute const functions ( and not release etc.) within the receiving function, should I then do:

void MyFunction(const LPDIRECT3DDEVICE9 d3ddev)
{
d3ddev->release; (should give a compiler error)
d3ddev->setrenderstate(....); (should be fine)
}

#11 SiCrane   Moderators   -  Reputation: 9676

Like
0Likes
Like

Posted 23 June 2013 - 06:32 PM

IDirect3DDevice9 has no const member functions. You basically can't do anything useful with a pointer to const IDirect3DDevice9. However, a const LPDIRECT3DDEVICE9 is a const pointer to a non-const IDirect3DDevice9. When you add const to a typedef of a pointer you get a const pointer type, not a pointer to a const object. It's equivalent to IDirect3DDevice9 * const not const IDirect3DDevice9 *.

#12 cozzie   Members   -  Reputation: 1777

Like
0Likes
Like

Posted 24 June 2013 - 05:13 AM

OK, so basically there's no reason to do it otherwise then just giving the LPDIRECT3DDEVICE9 as a parameter to the function, which is already a pointer to the idirect3ddevice9,

void LoadTextures(LPDIRECT3DDEVICE9 myDev)
{
D3dxfunction(....., myDev or &myDev)
myDev->setstreamsource etc.
}

This also means that this function is allowed to do everything with the device where myDev points too.
I was hoping there was a way to distinct what and what not a function is allowed to do with the device, but since the idirect3ddevice9 has no const member functions, I think this is a no go.

Would there be a possibility to distinct using the device just as a parameter/ reference when calling other functions who just need to know the device, versus functions who need to execute functions on the device itself:

1. D3dxcreatetexturefromfile(...., myDev);

Versus

2. myDev->avalidfunction (i.e. Reset, release, setpixelshader, setstreamsouce etc.)

That way I might be able to protect misusage of the device, in functions where I just need to pass it as a reference to a d3d(x) function.

#13 cozzie   Members   -  Reputation: 1777

Like
0Likes
Like

Posted 25 June 2013 - 04:18 AM

New question;

I've been doing some reading and looking at examples.
What I see often to 'solve' this is:

- the main d3d wrapper class has a ccomptr to the d3d device
- other classes who need access to the device have a private or protected d3d device ccomptr
Which is set when initializing an object of that class
- this 'copy' of the ccomptr to the device is not accesible from outside these classes

This seems like a good solution to me (for my d3dscene, mesh and skybox classes).
Things to think about:

- what if the device that's pointed too changes? (not that I expect this though)
- this doesn't prevent other classes then the main d3d wrapper class, to manipulate things on the device and run member functions on it

What do you think?

#14 cozzie   Members   -  Reputation: 1777

Like
0Likes
Like

Posted 26 June 2013 - 12:44 PM

I now implemented it as above, works fine.
I now pass the device pointer only once to an object of my classes, if more then one functions (mostly create or init) need the device pointer, I've created a private member containing a ccomptr where I save the pointer in the init/ create function for that object (which receives the pointer as a function parameter.

Finally I set the device ccomptr to NULL in both the constructor and destructor for these classes (mesh, d3dscene, skybox).
No more ->Release() calls now, with using ccomptr/ smart pointers (for idirect3ddevice9, idirect3dtexture9 and and id3dxmesh objects).

If you have any suggestions or remarks, please reply




Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS