Author Topic: Direct3D API misuse  (Read 1409 times)

0 Members and 1 Guest are viewing this topic.

Offline flexo

  • Major(1)
  • Posts: 8
Direct3D API misuse
« on: March 28, 2007, 01:17:25 pm »
Hi.

I'm working on Wine to fix the last remaining issues to run Soldat perfectly (tracked down the "messed up fonts" bug and severe performance issues with most DRI drivers) when I noticed that you seem to set the D3DRS_PATCHSEGMENTS render state to (DWORD)1 - as silly as it is that should be a float. See the ATI example at http://ati.amd.com/developer/samples/Radeon8500SimpleNPatch.
zip

No idea if this would cause any visible difference as (DWORD)1 is something between 0 < x < 1 when cast to float and this is quite meaningless in this context but you never know how drivers will interpret undefined values...

Cheers,
Felix

Offline FliesLikeABrick

  • Administrator
  • Flamebow Warrior
  • *****
  • Posts: 6144
    • Ultimate 13 Soldat
Re: Direct3D API misuse
« Reply #1 on: March 28, 2007, 01:21:44 pm »
Thanks for coming here to help get it working.  I hope that you look at Soldat after the new version is out, as a few things have changed. 

I will point the developer to this thread and have him take a look. 

Offline flexo

  • Major(1)
  • Posts: 8
Re: Direct3D API misuse
« Reply #2 on: March 28, 2007, 01:29:36 pm »
One small correction: Looks like the (DWORD)1 is cast to 0.0, not 0<x<1. But looking at the docs that still doesn't have a defined meaning as disabling is done with 1.0.

Offline Michal Marcinkowski

  • Creator of Soldat
  • Flagrunner
  • ******
  • Posts: 808
  • I ain't got time to bleed.
    • Soldat home page
Re: Direct3D API misuse
« Reply #3 on: March 29, 2007, 01:07:58 pm »
Hi,
I don't use D3DRS_PATCHSEGMENTS, so I don't know what it is about. I checked Direct3D8.pas and you are right about casting to DWord. Why is this a problem?

Code: [Select]
type
  _D3DRENDERSTATETYPE = type DWord;
  {$EXTERNALSYM _D3DRENDERSTATETYPE}
  D3DRENDERSTATETYPE = _D3DRENDERSTATETYPE;
  {$EXTERNALSYM D3DRENDERSTATETYPE}
  TD3DRenderStateType = _D3DRENDERSTATETYPE;

[...]
{$EXTERNALSYM D3DRS_PATCHEDGESTYLE}
  D3DRS_PATCHSEGMENTS             = TD3DRenderStateType(164);  // Number of segments per edge when drawing patches
[...]

Offline chrisgbk

  • Inactive Staff
  • Veteran
  • *****
  • Posts: 1739
Re: Direct3D API misuse
« Reply #4 on: March 30, 2007, 04:45:21 am »
Hi,
I don't use D3DRS_PATCHSEGMENTS, so I don't know what it is about. I checked Direct3D8.pas and you are right about casting to DWord. Why is this a problem?

Code: [Select]
type
  _D3DRENDERSTATETYPE = type DWord;
  {$EXTERNALSYM _D3DRENDERSTATETYPE}
  D3DRENDERSTATETYPE = _D3DRENDERSTATETYPE;
  {$EXTERNALSYM D3DRENDERSTATETYPE}
  TD3DRenderStateType = _D3DRENDERSTATETYPE;

[...]
{$EXTERNALSYM D3DRS_PATCHEDGESTYLE}
  D3DRS_PATCHSEGMENTS             = TD3DRenderStateType(164);  // Number of segments per edge when drawing patches
[...]

He didn't mean D3DRS_PATCHSEGMENTS was being cast to a DWORD, he meant the function that uses that was being called with the argument DWORD(1) which is incorrect.

Apparantly something like the following is happening(delphi style code):

Code: [Select]
Direct3DDevice.SetRenderState(D3DRS_PATCHSEGMENTS, 1);which is incorrect; the value 1 must be a float(1.0), which as binary is completely different, but theres the thing, you can't use a float value for this function directly.

Instead, you have to do this:

Code: [Select]
var
  segments: single;

segments := 1.0;
Direct3DDevice.SetRenderState(D3DRS_PATCHSEGMENTS, PDWORD(@sements)^);

Using the DWORD(1) results in a float value of 1.401298464e-045 being passed, which is invalid, and his point is that a driver that isn't well written may behave strange or crash when this invalid value is passed in.

I have a suspicion that it isn't in something you wrote yourself, as you said you don't use it, but instead is in one of the components you use.
« Last Edit: March 30, 2007, 04:48:08 am by chrisgbk »

Offline Michal Marcinkowski

  • Creator of Soldat
  • Flagrunner
  • ******
  • Posts: 808
  • I ain't got time to bleed.
    • Soldat home page
Re: Direct3D API misuse
« Reply #5 on: March 30, 2007, 06:28:45 am »
I searched the whole source code and it isn't used anywhere. Where could it be?

Offline chrisgbk

  • Inactive Staff
  • Veteran
  • *****
  • Posts: 1739
Re: Direct3D API misuse
« Reply #6 on: March 30, 2007, 08:59:40 am »
I searched the whole source code and it isn't used anywhere. Where could it be?

I checked the exe, and it is indeed called; twice, actually. And the order that other states are set around it, and the fact that it repeats itself immediately, leads me to believe that it is part of an object being created, perhaps some font drawing object, or the like. I'm making an educated guess that it's something to do with the font, because AFAIK soldat uses 2 different fonts, which would make sense.

D3DRS_ZENABLE = 0
D3DRS_FILLMODE = 3
D3DRS_CULLMODE  = 1
D3DRS_WRAP0 = 0
D3DRS_CLIPPING = 1
D3DRS_VERTEXBLEND = 0
D3DRS_CLIPPLANEENABLE = 0
D3DRS_PATCHSEGMENTS = 1
D3DRS_INDEXEDVERTEXBLENDENABLE = 0
D3DRS_ALPHABLENDENABLE = 1
D3DRS_SRCBLEND = 5
D3DRS_DESTBLEND = 6
D3DRS_BLENDOP = 1

and then this exact sequence is repeated. It is only ever done once in a given run of Soldat; changing maps, etc, will not cause it to be run again; however it is only ran when you load a map. (Presumably, that's when everything is created for the first time, and then it is kept in memory.)