DirectX9 and 2D rendering - Programmers Heaven

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Categories

DirectX9 and 2D rendering

ergonomy_joeergonomy_joe Posts: 6Member
Hi there,

Let me try to explain my problem.
My current application does the following.

* Filling a 2D buffer (a C array)
* Locking - copying the buffer - unlocking . of a Direct3D Surface in the default pool
* Stretching of the Surface to the backbuffer

And it works ... but with some problems on slower computers so I have to put a D3DLOCK_DONOTWAIT flag during the lock and just skip to the next frame if I get D3DERR_WASSTILLDRAWING error.

Then I read on a documentation that locking Surfaces in the default pool may be resource consumming. So here is the new process:

* Filling a 2D buffer
* Locking - copying the buffer - unlocking . of a Direct3D Surface in the SYSTEMMEM pool
* UpdateSurface from the SYSTEMMEM Surface to a DEFAULT_POOL surface
* Stretching of the Surface to the backbuffer

Well that's one more operation.
In fact I would like to know if there is really a TOP efficient way to present 2D buffers at a fixed frame rate ?
You got it, I'm working on an emulator program.

Another issue is that whichever of the two solutions, I need to have a DEFAULTPOOL Surface of 1024x1024. That's pretty big for one surface I guess. 4Mb for 16bits colors, or 8Mb for 32bits colors. Is this more efficient to split in say 4 512x512 surfaces, or 16 256x256 Surfaces, and repeat the Lock/Unlock(/Update)/Stretch operation as much time ?

Sorry to rely on you guys but any help is ok.

Joe
Fo-su to tomo ni aran koto wo

Comments

  • gautamgautam Posts: 642Member
    Q. Are you drawing pixels to the surface or creating a texture and texture mapping a quad.

    Option 1. If you are doing this then you should really do a dirty rectangle update and update only areas that have been modified.
    Option 2. Instead of updating this way create a texture at runtime and texture map a quad. I suppose this would be much much faster than sending pixels to the screen. In my opinion you should probably already be doing this.

    Regarding your second question - yeah you can do that using texture mapping of triangles/quads. Its pretty common to do so.

    What is this 2D array - what does it contain and are you locking for vertex buffers ?

    Sorry I am more of an OpenGL expert so its a little difficult to answer DirectX questions without enough information.




    : Hi there,
    :
    : Let me try to explain my problem.
    : My current application does the following.
    :
    : * Filling a 2D buffer (a C array)
    : * Locking - copying the buffer - unlocking . of a Direct3D Surface
    : in the default pool
    : * Stretching of the Surface to the backbuffer
    :
    : And it works ... but with some problems on slower computers so I
    : have to put a D3DLOCK_DONOTWAIT flag during the lock and just skip
    : to the next frame if I get D3DERR_WASSTILLDRAWING error.
    :
    : Then I read on a documentation that locking Surfaces in the default
    : pool may be resource consumming. So here is the new process:
    :
    : * Filling a 2D buffer
    : * Locking - copying the buffer - unlocking . of a Direct3D Surface
    : in the SYSTEMMEM pool
    : * UpdateSurface from the SYSTEMMEM Surface to a DEFAULT_POOL surface
    : * Stretching of the Surface to the backbuffer
    :
    : Well that's one more operation.
    : In fact I would like to know if there is really a TOP efficient way
    : to present 2D buffers at a fixed frame rate ?
    : You got it, I'm working on an emulator program.
    :
    : Another issue is that whichever of the two solutions, I need to have
    : a DEFAULTPOOL Surface of 1024x1024. That's pretty big for one
    : surface I guess. 4Mb for 16bits colors, or 8Mb for 32bits colors. Is
    : this more efficient to split in say 4 512x512 surfaces, or 16
    : 256x256 Surfaces, and repeat the Lock/Unlock(/Update)/Stretch
    : operation as much time ?
    :
    : Sorry to rely on you guys but any help is ok.
    :
    : Joe
    : Fo-su to tomo ni aran koto wo
    :
  • ergonomy_joeergonomy_joe Posts: 6Member
    Thanks for the reply.

    And no, I'm not using a quad. In fact, I've seen so far 3 solutions to "render" a 2D buffer to the screen (with DirectX).
    - StretchRect a Surface to the backbuffer
    - Draw a texture as a sprite
    - Draw a textured quad (as you suggested)
    if someone as other alternatives....?

    Anyway, in all cases you have to lockRect/copy/Unlock a Texture or a Surface at one point. And i guess this is the critical point.
    So my question stays: should one has a Surface(or Texture) in the device memory and works with it, or else has one Surface(or texture) in system memory, works with it, and then "copies" it to a Surface(or texture) in device memory ?

    As for your question, no I don't lock a vertex buffer, I lock a Surface.
    My 2D array contains the color pixel information of the current frame of emulated device.

    Thanx

    : Q. Are you drawing pixels to the surface or creating a texture and
    : texture mapping a quad.
    :
    : Option 1. If you are doing this then you should really do a dirty
    : rectangle update and update only areas that have been modified.
    : Option 2. Instead of updating this way create a texture at runtime
    : and texture map a quad. I suppose this would be much much faster
    : than sending pixels to the screen. In my opinion you should probably
    : already be doing this.
    :
    : Regarding your second question - yeah you can do that using texture
    : mapping of triangles/quads. Its pretty common to do so.
    :
    : What is this 2D array - what does it contain and are you locking for
    : vertex buffers ?
    :
    : Sorry I am more of an OpenGL expert so its a little difficult to
    : answer DirectX questions without enough information.

  • gautamgautam Posts: 642Member
    Use a quad and texture it. Drawing pixel by pixel or sending a bunch of pixel from system memory is going to be too slow.

    By the way "Draw a texture as a sprite" and "drawing a textured quad" is the same thing.

    And Use system memory :). I say this because read backs from the device memory or graphics ram is going to be expensive.

    : Thanks for the reply.
    :
    : And no, I'm not using a quad. In fact, I've seen so far 3 solutions
    : to "render" a 2D buffer to the screen (with DirectX).
    : - StretchRect a Surface to the backbuffer
    : - Draw a texture as a sprite
    : - Draw a textured quad (as you suggested)
    : if someone as other alternatives....?
    :
    : Anyway, in all cases you have to lockRect/copy/Unlock a Texture or a
    : Surface at one point. And i guess this is the critical point.
    : So my question stays: should one has a Surface(or Texture) in the
    : device memory and works with it, or else has one Surface(or texture)
    : in system memory, works with it, and then "copies" it to a
    : Surface(or texture) in device memory ?
    :
    : As for your question, no I don't lock a vertex buffer, I lock a
    : Surface.
    : My 2D array contains the color pixel information of the current
    : frame of emulated device.
    :
    : Thanx
    :
    : : Q. Are you drawing pixels to the surface or creating a texture and
    : : texture mapping a quad.
    : :
    : : Option 1. If you are doing this then you should really do a dirty
    : : rectangle update and update only areas that have been modified.
    : : Option 2. Instead of updating this way create a texture at runtime
    : : and texture map a quad. I suppose this would be much much faster
    : : than sending pixels to the screen. In my opinion you should probably
    : : already be doing this.
    : :
    : : Regarding your second question - yeah you can do that using texture
    : : mapping of triangles/quads. Its pretty common to do so.
    : :
    : : What is this 2D array - what does it contain and are you locking for
    : : vertex buffers ?
    : :
    : : Sorry I am more of an OpenGL expert so its a little difficult to
    : : answer DirectX questions without enough information.
    :
    :
  • ergonomy_joeergonomy_joe Posts: 6Member

    In my case (emulator application) I NEED to somehow send the virtual screen buffer to the video card every frame, and it looks like the fastest way to do that in DirectX is updating a Surface, and then stretchRect it to the backbuffer. Call it "drawing pixel by pixel" or "sending a bunch of pixel" if you like, I don't have the choice. This is the base of the application: creating a 2D buffer each frame and display it on the monitor.

    You seem to prefer the quad version. Why do you think it would be faster ?
    Do you mean that lockcopy/unlock texture is faster than Surface ?
    If your texture is in system memory (which I agree may be really fast for lock/copy/unlock) it is be sent to the video ram each frame, right ?


    : Use a quad and texture it. Drawing pixel by pixel or sending a bunch
    : of pixel from system memory is going to be too slow.
    :
    : By the way "Draw a texture as a sprite" and "drawing a textured
    : quad" is the same thing.
    :
    : And Use system memory :). I say this because read backs from the
    : device memory or graphics ram is going to be expensive.

  • gautamgautam Posts: 642Member
    There is a function called glDrawPixels in OpenGL which is similar to what you are doing - If you go to "FAQ 22.070 Why are glDrawPixels() and glReadPixels() so slow?" it might answer your question partly. It gives a far better explanation than what I could give.

    http://www.opengl.org/resources/faq/technical/performance.htm

    Also note that drawing triangles are optimized in the driver compared to drawing/updating only pixels. Even writing to texture probably will be optimized because it used to be quite common to write data into a texture from the framebuffer, but I am no sure because it has been quite some time since I did any graphics programming.

    :
    : In my case (emulator application) I NEED to somehow send the virtual
    : screen buffer to the video card every frame, and it looks like the
    : fastest way to do that in DirectX is updating a Surface, and then
    : stretchRect it to the backbuffer. Call it "drawing pixel by pixel"
    : or "sending a bunch of pixel" if you like, I don't have the choice.
    : This is the base of the application: creating a 2D buffer each frame
    : and display it on the monitor.
    :
    : You seem to prefer the quad version. Why do you think it would be
    : faster ?
    : Do you mean that lockcopy/unlock texture is faster than Surface ?
    : If your texture is in system memory (which I agree may be really
    : fast for lock/copy/unlock) it is be sent to the video ram each
    : frame, right ?
    :
    :
    : : Use a quad and texture it. Drawing pixel by pixel or sending a bunch
    : : of pixel from system memory is going to be too slow.
    : :
    : : By the way "Draw a texture as a sprite" and "drawing a textured
    : : quad" is the same thing.
    : :
    : : And Use system memory :). I say this because read backs from the
    : : device memory or graphics ram is going to be expensive.
    :
    :
Sign In or Register to comment.