Sign in to follow this  
awickedmind

OpenGL Shader pipeline differences OGL DX

Recommended Posts

awickedmind    100
I've been wanting to write an engine with both an OpenGL and an Directx path (primarily DX10 and OGL 2/3). Having programmed OpenGL for a long time I'm having some problems creating my "Graphics Abstraction Layer". The biggest problem for me currently are shaders.

The biggest difference I've noticed is the lack of an program a la glCreateProgram in DX10. That in it self is not an issue but I'm starting to worry about costs for different operations. I'm wondring when DX10 does its shader linkage and how costly it is. For example if swap shaders for different passes I would change using glUseProgram. This does not make sense in a DX10 context (at least not to my knowledge). So my question:

If I wish to swap shaders ~5 times a frame is linkage so cheap on DX10 hardware that it's just to attach my new vertex/pixel shader setup and in OpenGL do the same and then call glLinkProgram (which I avoid during my main loop otherwise). Is there a similar DX10 call? Is an ubershader the only practically viable way? How does the DX9 pipeline differ (for future branches)?

A link for a read up or just a straight answer would be nice. I haven't found anything that truly clarifies this for me on Google...

Share this post


Link to post
Share on other sites
Krohm    5031
I don't have a clear vision of this performance as well, but I think you're overrating GL's linking stage.
There's chance GL's linking stage is yet another relic of an already conceptually distant past, you might read about ARB_separate_shader_objects.
I am sure I'll get bashed about performance by saying this, but considering that there's an official extension to do that, looks like nobody really cares about the old extra perf from binding stages together once.

To deal with the mix-and-match approach you probably have to "meta-link" the shaders yourself and expand each combination in a single program. Let me say I never liked this approach since day 1.

I sincerely wish you'll never have to go back to D3D9, but in the unfortunate case you'll need to, you'll find out its shading pipe works more or less like a very stupid D3D10 pipe.

Share this post


Link to post
Share on other sites
16bit_port    180
Quote:

The biggest difference I've noticed is the lack of an program a la glCreateProgram in DX10.


HLSL's Effect is equivalent to GLSL's Program. They can be created with D3DX10CreateEffectFromFile.

With that said, you can use different shaders for different passes with Effects :

technique10 ShaderModel4_Technique
{
pass P0
{
SetVertexShader( CompileShader( vs_4_0, Main_VS1() ) );
SetGeometryShader( NULL );
SetPixelShader( CompileShader( ps_4_0, Main_PS1() ) );
}
pass P1
{
SetVertexShader( CompileShader( vs_4_0, Main_VS2() ) );
SetGeometryShader( NULL );
SetPixelShader( CompileShader( ps_4_0, Main_PS2() ) );
}
}




since the above code sample is compiled through one API interface (D3DX10CreateEffectFromFile) as opposed to the multiple calls with glAttachShader, I would assume that D3D10 does it shader linkage slighty faster than OpenGL.

Share this post


Link to post
Share on other sites
swiftcoder    18437
Quote:
Original post by 16bit_port
HLSL's Effect is equivalent to GLSL's Program. They can be created with D3DX10CreateEffectFromFile.
Except that effects are purely a convenience layer built on top of the underlying shaders - they don't actually add any functionality of their own.

Share this post


Link to post
Share on other sites
rubicondev    296
Effect files are a decent way to prototype complex shaders, but for in-game use they're just a pain in the ass.

If your engine just services requests from effects files then you will see pathetic performance and be spending half your dev time adding lighting options and stuff.

Better to just write the core pixel generating code in a file and reference functions to do lighting and shadows and stuff. And by the time you get that far, the power of effects files becomes lost anyway. They're just the wrong tool for the job.

Playing in rendermonkey has a place, but that's not how your game should run imo.

Share this post


Link to post
Share on other sites
16bit_port    180
Quote:

but for in-game use they're just a pain in the ass.


They weren't that bad in D3D9, but they did changed stuff around in D3D10 where it did become kind of annoying.

Quote:

If your engine just services requests from effects files then you will see pathetic performance and be spending half your dev time adding lighting options and stuff.

How bad of a performance are we talking about here?

Quote:

Better to just write the core pixel generating code in a file and reference functions to do lighting and shadows and stuff.

What do you mean? Do you mean write the shaders without Effect, and use these :

ID3D10Device::CreateVertexShader
ID3D10Device::CreatePixelShader

instead?

Share this post


Link to post
Share on other sites
MJP    19788
Effects are mostly designed for convenience. They totally abstract away shader parameter management, which allows you to freely set parameters without having to worry at all about pipeline state or data management. Naturally this doesn't scale for setting lots of effects and parameters, since you'll start to spend significant amounts of time touch data from disparate memory locations (or on PC you can start to incur significant API overhead). If you want less overhead, you need to design your shader constant (constant buffer) layout and the layout of CPU-side data structures to match the actual usage patterns. This means clearly separating parameters by how often they change, and storing the CPU data in memory in the same layout used by the shaders so that you can quickly transfer it.

Any in regards to the OP's question...from what I know linkage between the different shader stages is not a big deal. I don't think most GPU's do anything fancy in that regard. There will probably be some shader-side work for unpacking vertex attributes, but that should be handled by input layouts. Either way...5 changes a frame is nothing at all to worry about.

Share this post


Link to post
Share on other sites
remigius    1172
Quote:
Original post by Hodgman
I know a 360 game (that I can't name) that spends 30% of it's CPU time inside the effect API... ;(
We gave up on effects after that projcet.


Can you disclose what the main sinks were for this lost CPU time? With my hobbyist tinkering I found that the effects framework can be made to run quite a bit smoother by hanging on to the native handles of constants instead of addressing them by their names, but otherwise I haven't seen such performance drains. Just curious mind you, not arguing effects are super efficient when you hang on to the handles [smile]

Share this post


Link to post
Share on other sites
Hodgman    51339
Quote:
Original post by remigius
Can you disclose what the main sinks were for this lost CPU time?
IIRC it was mostly setting uniform data, like matrices, model colours, etc... Without effects we put this data into specific registers, so they don't have to be re-uploaded with each shader switch.

Share this post


Link to post
Share on other sites
awickedmind    100
Thanks for all the responses! Things are becoming a bit clearer for me.

Effects don't appeal to me since the break any kind of GAL pipeline which branches off into more API-specific code later down the line. But for prototyping they look neat. Also, based on the all the replies I won't reconsider it.

Yes, I wish to use the ID3D10Device::CreateVertexShader and the ID3D10Device::CreatePixelShader. Even though I've been using OpenGL for a long time the DX10 approach makes a lot of sense to me. Coming from OpenGL though I felt a bit uneasy about when linkage occurs (on assignment per shader I presume). My issue is more of how to not break my OpenGL code when designing for both systems (forcing me to make a more loose abstraction which will give me some overhead).

Further I'm guessing that the cost is also based on the HW generation, with DX9/10 cards having cheap linkage?

I was worried the driver would do expensive stuff on the CPU side when linking using glLinkProgram but if it's a relic then all is well. There is still an issue of relinking and again relocating all my attributes and constants (something I suppose DX10 need not worry about because of the IA stage?). But I haven't fully decided yet on how I wish for my pipeline to look.

@ Krohm: Thanks a lot for the link, this would solve a lot of issues for me if implemented on my target platforms (OSX is still a bit slow here). I was actually designing to "meta-link" keeping track of different combinations. Let's just say the solution turned out to be less elegant...

Share this post


Link to post
Share on other sites
remigius    1172
Quote:
Original post by Hodgman
IIRC it was mostly setting uniform data, like matrices, model colours, etc... Without effects we put this data into specific registers, so they don't have to be re-uploaded with each shader switch.


Thanks for the response, I just realized keeping data around across shader switches isn't something I've considered doing before [smile]

I have to ask however, isn't this what EffectPool sharing should fix, or is the performance of the EffectPool part of the problem?

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  

  • Partner Spotlight

  • Similar Content

    • By pseudomarvin
      I assumed that if a shader is computationally expensive then the execution is just slower. But running the following GLSL FS instead just crashes
      void main() { float x = 0; float y = 0; int sum = 0; for (float x = 0; x < 10; x += 0.00005) { for (float y = 0; y < 10; y += 0.00005) { sum++; } } fragColor = vec4(1, 1, 1 , 1.0); } with unhandled exception in nvoglv32.dll. Are there any hard limits on the number of steps/time that a shader can take before it is shut down? I was thinking about implementing some time intensive computation in shaders where it would take on the order of seconds to compute a frame, is that possible? Thanks.
    • By Arulbabu Donbosco
      There are studios selling applications which is just copying any 3Dgraphic content and regenerating into another new window. especially for CAVE Virtual reality experience. so that the user opens REvite or CAD or any other 3D applications and opens a model. then when the user selects the rendered window the VR application copies the 3D model information from the OpenGL window. 
      I got the clue that the VR application replaces the windows opengl32.dll file. how this is possible ... how can we copy the 3d content from the current OpenGL window.
      anyone, please help me .. how to go further... to create an application like VR CAVE. 
       
      Thanks
    • By cebugdev
      hi all,

      i am trying to build an OpenGL 2D GUI system, (yeah yeah, i know i should not be re inventing the wheel, but this is for educational and some other purpose only),
      i have built GUI system before using 2D systems such as that of HTML/JS canvas, but in 2D system, i can directly match a mouse coordinates to the actual graphic coordinates with additional computation for screen size/ratio/scale ofcourse.
      now i want to port it to OpenGL, i know that to render a 2D object in OpenGL we specify coordiantes in Clip space or use the orthographic projection, now heres what i need help about.
      1. what is the right way of rendering the GUI? is it thru drawing in clip space or switching to ortho projection?
      2. from screen coordinates (top left is 0,0 nd bottom right is width height), how can i map the mouse coordinates to OpenGL 2D so that mouse events such as button click works? In consideration ofcourse to the current screen/size dimension.
      3. when let say if the screen size/dimension is different, how to handle this? in my previous javascript 2D engine using canvas, i just have my working coordinates and then just perform the bitblk or copying my working canvas to screen canvas and scale the mouse coordinates from there, in OpenGL how to work on a multiple screen sizes (more like an OpenGL ES question).
      lastly, if you guys know any books, resources, links or tutorials that handle or discuss this, i found one with marekknows opengl game engine website but its not free,
      Just let me know. Did not have any luck finding resource in google for writing our own OpenGL GUI framework.
      IF there are no any available online, just let me know, what things do i need to look into for OpenGL and i will study them one by one to make it work.
      thank you, and looking forward to positive replies.
    • By fllwr0491
      I have a few beginner questions about tesselation that I really have no clue.
      The opengl wiki doesn't seem to talk anything about the details.
       
      What is the relationship between TCS layout out and TES layout in?
      How does the tesselator know how control points are organized?
          e.g. If TES input requests triangles, but TCS can output N vertices.
             What happens in this case?
      In this article,
      http://www.informit.com/articles/article.aspx?p=2120983
      the isoline example TCS out=4, but TES in=isoline.
      And gl_TessCoord is only a single one.
      So which ones are the control points?
      How are tesselator building primitives?
    • By Orella
      I've been developing a 2D Engine using SFML + ImGui.
      Here you can see an image
      The editor is rendered using ImGui and the scene window is a sf::RenderTexture where I draw the GameObjects and then is converted to ImGui::Image to render it in the editor.
      Now I need to create a 3D Engine during this year in my Bachelor Degree but using SDL2 + ImGui and I want to recreate what I did with the 2D Engine. 
      I've managed to render the editor like I did in the 2D Engine using this example that comes with ImGui. 
      3D Editor preview
      But I don't know how to create an equivalent of sf::RenderTexture in SDL2, so I can draw the 3D scene there and convert it to ImGui::Image to show it in the editor.
      If you can provide code will be better. And if you want me to provide any specific code tell me.
      Thanks!
  • Popular Now