edgar-mtz-e / slimdx

Automatically exported from code.google.com/p/slimdx
0 stars 0 forks source link

BaseTexture can't be created from 'any' DX texture #452

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
Hi guys,

I'm developing something conceptually similar to Gamebryo's Command buffer
idea (see http://www.emergent.net/GameFest2008 ) but using SlimDX.

The idea is to make a proxy that records all calls to a D3D9 device, then
replays them, presumably in another thread.

The recording code for calls involving DX COM objects looks something like
this:
        public IndexBuffer Indices
        {
            set
            {
                Marshal.AddRef(value.ComPointer);
                _writer.Write(value.ComPointer);
            }
        }

Then, the playback goes something like this:

IntPtr indicesPtr;
reader.Read(out indicesPtr);
IndexBuffer indices = IndexBuffer.FromPointer(indicesPtr);
Device.Indices = indices;

The idea is pretty simple. My problem however is that BaseTexture doesn't
have a FromPointer() method. As far as I can tell there is no specific need
for BaseTexture to be abstract (since DX already handles textures only
through their base class) and, in fact, can be implemented as a concrete
class just by removing the abstract keyword and using COMOBJECT instead of
COMOBJECT_BASE.

Well, how about it?

Regards,
Stefan.

Original issue reported on code.google.com by tai...@gmail.com on 16 Mar 2009 at 7:03

GoogleCodeExporter commented 9 years ago
Yes and no. It screws up SlimDX's internal management if it doesn't always have 
the 
true concrete type of an object. (This was a known limitation going in which we 
accepted.) So making Resource or BaseTexture into concrete classes is not 
possible.

However, we can quite easily query a resource to see what it is, and chain to 
the 
correct FromPointer call. That's conveniently built right into the D3D 
interface. 
(And it's why we accepted the aforementioned drawback of the internals.) It 
hasn't 
been done yet mainly because nobody's actually wanted that particular 
functionality 
yet. It shouldn't be much trouble to add for March.

Original comment by promit....@gmail.com on 17 Mar 2009 at 12:08

GoogleCodeExporter commented 9 years ago
Oh, that's of course assuming that DirectX is well behaved COM-wise in this 
regard, 
which can be hit and miss. Have you considered storing Object/ComObject instead 
of 
IntPtr? It will probably be easier and faster than round-tripping through 
DirectX.

Original comment by promit....@gmail.com on 17 Mar 2009 at 12:11

GoogleCodeExporter commented 9 years ago
N.B. that D3D10 supports exactly this (Resource, for example, is non-abstract) 
as per a user request a 
while back. It works fine, as near as I can tell. What issues did we have with 
internal bookkeeping?

We should support this consistently, one way or another. I'm inclined to favor 
allowing the construction of 
"intermediate" classes like BaseTexture (with the caveat that doing so means 
you can never downcast to the 
most-derived type of texture) for interop scenarios like this. I'd care less if 
we could prove that all such 
intermediate objects through the APIs we wrap can be successively handled in 
the "figure out the most-
derived type and really create that" scenario -- I have a hunch this is 
possible via QI'ing at least.

Also, if we disallow the construction of intermediate objects it may well break 
the D3D10 API for at least 
one user.

Original comment by josh.petrie on 17 Mar 2009 at 12:37

GoogleCodeExporter commented 9 years ago
"with the caveat that doing so means you can never downcast to the 
most-derived type of texture"
Yes, that's the problem -- the ObjectTable records it as the class available at 
first 
construction. It's not actually a problem for the OP of this issue, because he 
already 
has an existing SlimDX object of the correct type.

Recap: SlimDX stores an internal table of objects, keyed by native pointer 
value. So if 
you create a Texture, that is inserted into the table as a Texture in the 
value. If the 
first SlimDX saw of the object were a BaseTexture, then the new table entry 
would be a 
BaseTexture even though it's actually a Texture. Unfortunately, this would 
disallow EVER 
recovering the correct base type, because Texture.FromPointer will run a check 
against 
the table, attempt to blind cast the value, and fail.

I have a problem with being able to create that situation where the true class 
can't be 
recovered, myself. It looks very broken if a user runs into it. But every 
instance I 
know of in D3D 9 where it is possible, we can simply sidestep it, because it 
provides us 
with the correct type. So we can provide a perfectly good Resource.FromPointer 
implementation, that will first QI to IDirect3DResource9, then ask for the true 
base 
type and chain to the appropriate constructor (which will then QI again for its 
expected 
type). Should work beautifully internally and externally both, with no weird 
side 
effects.

Original comment by promit....@gmail.com on 17 Mar 2009 at 1:01

GoogleCodeExporter commented 9 years ago
Pri boost. If someone wants to take this off my hands, that would be fabulous.

Original comment by promit....@gmail.com on 26 Mar 2009 at 3:44

GoogleCodeExporter commented 9 years ago
Taken!

Original comment by Mike.Popoloski on 26 Mar 2009 at 3:48

GoogleCodeExporter commented 9 years ago
I've checked in Resource::FromPointer, which is as much of this change as will 
make 
it in for March.

Original comment by promit....@gmail.com on 29 Mar 2009 at 10:03

GoogleCodeExporter commented 9 years ago
This issue was closed by r1122.

Original comment by Mike.Popoloski on 25 May 2009 at 2:48

GoogleCodeExporter commented 9 years ago
Finished this change for D3D10. There may be other locations that this is 
needed, but
I'm going to close this and let users open new issues if they find one.

Original comment by Mike.Popoloski on 25 May 2009 at 2:49