How do I know if I'm abstracting graphics APIs too tightly?











up vote
21
down vote

favorite
2












When making a renderer that supports multiple graphics APIs, you would typically want to abstract your code in some sort of low level library that is tied with some graphics API like OpenGL, Vulkan, D3D11 and so on;



They work very differently from each other, so making a good generic API becomes essential;
I've read that you would typically want to use a "back-end" that implements the basic functionality for each API you want to support, and a "front-end" which is what is used by the programmer to draw stuff on the screen.



How do I know if I'm making too much of a tight abstraction?










share|improve this question




















  • 5




    Are you 100% certain that your wrapper + Vulkan or D3D11 is faster than just always using OpenGL?
    – Mooing Duck
    Nov 30 at 22:58












  • @Mooing Duck if used correctly, yes.
    – Gabriele Vierti
    Dec 1 at 7:34






  • 3




    I would seriously doubt that. Most of the gains in Vulkan come from being very low-level and doing things in a very peculiar, specific way. Something that is generic enough to also do the same seamlessly in OpenGL or D3D almost certainly can't do that. Reimplementing the same stuff as OpenGL does (like many Vulkan tutorials do, ironically) results in 99.99% the same performance, with 20 times the work.
    – Damon
    Dec 1 at 15:46










  • @Damon that's right, but newer APIs are specifically designed (and not adapted like OpenGL) to work on modern gpus; speaking of Vulkan, you can pretty much use the same API on every supported platform, contrarily to OpenGL, where you need to use the "Embedded Systems" version. Other than less cpu overhead and fancy features we don't have much, but in the future we might have some pretty surprising techniques that may run faster using Vk or D3D12 rather than OGL or D3D11
    – Gabriele Vierti
    Dec 1 at 16:04















up vote
21
down vote

favorite
2












When making a renderer that supports multiple graphics APIs, you would typically want to abstract your code in some sort of low level library that is tied with some graphics API like OpenGL, Vulkan, D3D11 and so on;



They work very differently from each other, so making a good generic API becomes essential;
I've read that you would typically want to use a "back-end" that implements the basic functionality for each API you want to support, and a "front-end" which is what is used by the programmer to draw stuff on the screen.



How do I know if I'm making too much of a tight abstraction?










share|improve this question




















  • 5




    Are you 100% certain that your wrapper + Vulkan or D3D11 is faster than just always using OpenGL?
    – Mooing Duck
    Nov 30 at 22:58












  • @Mooing Duck if used correctly, yes.
    – Gabriele Vierti
    Dec 1 at 7:34






  • 3




    I would seriously doubt that. Most of the gains in Vulkan come from being very low-level and doing things in a very peculiar, specific way. Something that is generic enough to also do the same seamlessly in OpenGL or D3D almost certainly can't do that. Reimplementing the same stuff as OpenGL does (like many Vulkan tutorials do, ironically) results in 99.99% the same performance, with 20 times the work.
    – Damon
    Dec 1 at 15:46










  • @Damon that's right, but newer APIs are specifically designed (and not adapted like OpenGL) to work on modern gpus; speaking of Vulkan, you can pretty much use the same API on every supported platform, contrarily to OpenGL, where you need to use the "Embedded Systems" version. Other than less cpu overhead and fancy features we don't have much, but in the future we might have some pretty surprising techniques that may run faster using Vk or D3D12 rather than OGL or D3D11
    – Gabriele Vierti
    Dec 1 at 16:04













up vote
21
down vote

favorite
2









up vote
21
down vote

favorite
2






2





When making a renderer that supports multiple graphics APIs, you would typically want to abstract your code in some sort of low level library that is tied with some graphics API like OpenGL, Vulkan, D3D11 and so on;



They work very differently from each other, so making a good generic API becomes essential;
I've read that you would typically want to use a "back-end" that implements the basic functionality for each API you want to support, and a "front-end" which is what is used by the programmer to draw stuff on the screen.



How do I know if I'm making too much of a tight abstraction?










share|improve this question















When making a renderer that supports multiple graphics APIs, you would typically want to abstract your code in some sort of low level library that is tied with some graphics API like OpenGL, Vulkan, D3D11 and so on;



They work very differently from each other, so making a good generic API becomes essential;
I've read that you would typically want to use a "back-end" that implements the basic functionality for each API you want to support, and a "front-end" which is what is used by the programmer to draw stuff on the screen.



How do I know if I'm making too much of a tight abstraction?







graphics-programming






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Dec 1 at 8:37

























asked Nov 30 at 8:06









Gabriele Vierti

350214




350214








  • 5




    Are you 100% certain that your wrapper + Vulkan or D3D11 is faster than just always using OpenGL?
    – Mooing Duck
    Nov 30 at 22:58












  • @Mooing Duck if used correctly, yes.
    – Gabriele Vierti
    Dec 1 at 7:34






  • 3




    I would seriously doubt that. Most of the gains in Vulkan come from being very low-level and doing things in a very peculiar, specific way. Something that is generic enough to also do the same seamlessly in OpenGL or D3D almost certainly can't do that. Reimplementing the same stuff as OpenGL does (like many Vulkan tutorials do, ironically) results in 99.99% the same performance, with 20 times the work.
    – Damon
    Dec 1 at 15:46










  • @Damon that's right, but newer APIs are specifically designed (and not adapted like OpenGL) to work on modern gpus; speaking of Vulkan, you can pretty much use the same API on every supported platform, contrarily to OpenGL, where you need to use the "Embedded Systems" version. Other than less cpu overhead and fancy features we don't have much, but in the future we might have some pretty surprising techniques that may run faster using Vk or D3D12 rather than OGL or D3D11
    – Gabriele Vierti
    Dec 1 at 16:04














  • 5




    Are you 100% certain that your wrapper + Vulkan or D3D11 is faster than just always using OpenGL?
    – Mooing Duck
    Nov 30 at 22:58












  • @Mooing Duck if used correctly, yes.
    – Gabriele Vierti
    Dec 1 at 7:34






  • 3




    I would seriously doubt that. Most of the gains in Vulkan come from being very low-level and doing things in a very peculiar, specific way. Something that is generic enough to also do the same seamlessly in OpenGL or D3D almost certainly can't do that. Reimplementing the same stuff as OpenGL does (like many Vulkan tutorials do, ironically) results in 99.99% the same performance, with 20 times the work.
    – Damon
    Dec 1 at 15:46










  • @Damon that's right, but newer APIs are specifically designed (and not adapted like OpenGL) to work on modern gpus; speaking of Vulkan, you can pretty much use the same API on every supported platform, contrarily to OpenGL, where you need to use the "Embedded Systems" version. Other than less cpu overhead and fancy features we don't have much, but in the future we might have some pretty surprising techniques that may run faster using Vk or D3D12 rather than OGL or D3D11
    – Gabriele Vierti
    Dec 1 at 16:04








5




5




Are you 100% certain that your wrapper + Vulkan or D3D11 is faster than just always using OpenGL?
– Mooing Duck
Nov 30 at 22:58






Are you 100% certain that your wrapper + Vulkan or D3D11 is faster than just always using OpenGL?
– Mooing Duck
Nov 30 at 22:58














@Mooing Duck if used correctly, yes.
– Gabriele Vierti
Dec 1 at 7:34




@Mooing Duck if used correctly, yes.
– Gabriele Vierti
Dec 1 at 7:34




3




3




I would seriously doubt that. Most of the gains in Vulkan come from being very low-level and doing things in a very peculiar, specific way. Something that is generic enough to also do the same seamlessly in OpenGL or D3D almost certainly can't do that. Reimplementing the same stuff as OpenGL does (like many Vulkan tutorials do, ironically) results in 99.99% the same performance, with 20 times the work.
– Damon
Dec 1 at 15:46




I would seriously doubt that. Most of the gains in Vulkan come from being very low-level and doing things in a very peculiar, specific way. Something that is generic enough to also do the same seamlessly in OpenGL or D3D almost certainly can't do that. Reimplementing the same stuff as OpenGL does (like many Vulkan tutorials do, ironically) results in 99.99% the same performance, with 20 times the work.
– Damon
Dec 1 at 15:46












@Damon that's right, but newer APIs are specifically designed (and not adapted like OpenGL) to work on modern gpus; speaking of Vulkan, you can pretty much use the same API on every supported platform, contrarily to OpenGL, where you need to use the "Embedded Systems" version. Other than less cpu overhead and fancy features we don't have much, but in the future we might have some pretty surprising techniques that may run faster using Vk or D3D12 rather than OGL or D3D11
– Gabriele Vierti
Dec 1 at 16:04




@Damon that's right, but newer APIs are specifically designed (and not adapted like OpenGL) to work on modern gpus; speaking of Vulkan, you can pretty much use the same API on every supported platform, contrarily to OpenGL, where you need to use the "Embedded Systems" version. Other than less cpu overhead and fancy features we don't have much, but in the future we might have some pretty surprising techniques that may run faster using Vk or D3D12 rather than OGL or D3D11
– Gabriele Vierti
Dec 1 at 16:04










3 Answers
3






active

oldest

votes

















up vote
42
down vote



accepted










First of all, consider if it is actually worth it to support more than one graphics API. Just using OpenGL will cover most platforms and will be "good enough" for all but the most graphically ambitious projects. Unless you work for a very large game studio which can afford to sink several thousand person-hours into implementing and testing multiple rendering backends and unless there are some DirectX or Vulcan specific features you really want to show off, it is usually not worth the hassle. Especially considering that you can save a lot of work by using an abstraction layer someone else created (a 3rd party library or game engine).



But let's assume that you already evaluated your options and came to the conclusion that it is both viable and worth the time to roll your own.



Then the main judge of your abstraction layer's software architecture are your front-end programmers.




  • Are they able to implement the game systems they want to implement without having to wonder about any low-level details?

  • Are they able to completely ignore that there is more than one graphics API?

  • Would it theoretically be possible to add yet another rendering backend without changing any of the front-end code?


If so, you succeeded.






share|improve this answer



















  • 2




    One additional suggestion: is it worth emphasizing that the goal is to achieve the goals in the bullet points with the minimal level of effort--to just hit the target and go no further? Otherwise each one of these can turn into a rabbit hole for the typical developer who (myself included) often doesn't know when to leave good-enough alone. :) And also that the only reliable way to judge success is to develop and test the API iteratively with actual users; it's impossible to guess accurately, and leads to a rabbit hole scenario of over-engineering.
    – bob
    Nov 30 at 15:48








  • 5




    I would add that, if you really do have to support multiple graphics libraries, there's almost certainly an off-the-shelf one that does everything you need to, so even then you really shouldn't roll your own. (Of course, there are exceptions, but if you're inexperienced enough to ask "how tight of an abstraction should I make" you're probably not working on a project that requires you to do it)
    – Nic Hartley
    Nov 30 at 19:27












  • I'm not a graphics dev, but looking at compatibility frameworks from the history of databases and OSes, I'd add that it's almost certainly just not worth it to make your own general framework. The framework will almost certainly have to sacrifice performance for compatibility, which probably means you can't do much with those specialized features anyway. Existing frameworks are nearly certain to handle those issues better due to wider usage. Now, if you have the massive budget you describe and want to build a specialized framework (say for one game or series), that might be more doable.
    – jpmc26
    Dec 2 at 21:18




















up vote
5
down vote













Start by identifying what you actually need out of the "wrapper" part of the API. It's generally very, very simple: you need the basic resources (buffers, shaders, textures, pipeline state) and a way to use those resources to construct a frame by submitting some draw calls.



Try to keep any high-level logic out of the wrapper portion of the API. If you implement a clever scene culling technique in this portion of the API, well now you are on the hook to duplicate that logic in all of the backend implementations. That's a lot of extra effort, so keep it simple. Scene management should be part of a higher-level portion of the API that uses the wrapper rather than being part of the wrapper itself.



Choose the targets you will support and understand them. It's hard to write decent wrappers for "everything," and you probably don't need to (arguably you don't need to write a single wrapper, either, as noted in Philipp's answer). It's almost impossible to write a decent wrapper if you don't know the APIs you're going to wrap already.



Evaluate the state of your API regularly. It should in general have a smaller surface area than the underlying wrapped APIs; if you find yourself creating one-to-one wrapper types for every D3D structure or every OpenGL function call you are probably veering off course.



Look at what work has gone before. Sokol and BGFX are APIs that provide levels of agnosticism that may be useful to you, and are relatively easy to understand (the former especially).






share|improve this answer




























    up vote
    2
    down vote













    Another point not yet mentioned which you should consider is what your performance goals are. If your goal is to have a graphics library that will yield good performance out of a cheap hardware platform, but also be usable on a variety of platforms that are vastly more powerful but use a different API, it may make sense to design your API around whatever abstractions are used natively on the platform where performance is an issue. Even if this causes a 50% speed degradation on the more powerful platforms, it may be worth it if it allows a 20% speed improvement on the platform where performance matters most.






    share|improve this answer





















      Your Answer





      StackExchange.ifUsing("editor", function () {
      return StackExchange.using("mathjaxEditing", function () {
      StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix) {
      StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
      });
      });
      }, "mathjax-editing");

      StackExchange.ifUsing("editor", function () {
      StackExchange.using("externalEditor", function () {
      StackExchange.using("snippets", function () {
      StackExchange.snippets.init();
      });
      });
      }, "code-snippets");

      StackExchange.ready(function() {
      var channelOptions = {
      tags: "".split(" "),
      id: "53"
      };
      initTagRenderer("".split(" "), "".split(" "), channelOptions);

      StackExchange.using("externalEditor", function() {
      // Have to fire editor after snippets, if snippets enabled
      if (StackExchange.settings.snippets.snippetsEnabled) {
      StackExchange.using("snippets", function() {
      createEditor();
      });
      }
      else {
      createEditor();
      }
      });

      function createEditor() {
      StackExchange.prepareEditor({
      heartbeatType: 'answer',
      convertImagesToLinks: false,
      noModals: true,
      showLowRepImageUploadWarning: true,
      reputationToPostImages: null,
      bindNavPrevention: true,
      postfix: "",
      imageUploader: {
      brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
      contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
      allowUrls: true
      },
      onDemand: true,
      discardSelector: ".discard-answer"
      ,immediatelyShowMarkdownHelp:true
      });


      }
      });














      draft saved

      draft discarded


















      StackExchange.ready(
      function () {
      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fgamedev.stackexchange.com%2fquestions%2f165761%2fhow-do-i-know-if-im-abstracting-graphics-apis-too-tightly%23new-answer', 'question_page');
      }
      );

      Post as a guest















      Required, but never shown

























      3 Answers
      3






      active

      oldest

      votes








      3 Answers
      3






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes








      up vote
      42
      down vote



      accepted










      First of all, consider if it is actually worth it to support more than one graphics API. Just using OpenGL will cover most platforms and will be "good enough" for all but the most graphically ambitious projects. Unless you work for a very large game studio which can afford to sink several thousand person-hours into implementing and testing multiple rendering backends and unless there are some DirectX or Vulcan specific features you really want to show off, it is usually not worth the hassle. Especially considering that you can save a lot of work by using an abstraction layer someone else created (a 3rd party library or game engine).



      But let's assume that you already evaluated your options and came to the conclusion that it is both viable and worth the time to roll your own.



      Then the main judge of your abstraction layer's software architecture are your front-end programmers.




      • Are they able to implement the game systems they want to implement without having to wonder about any low-level details?

      • Are they able to completely ignore that there is more than one graphics API?

      • Would it theoretically be possible to add yet another rendering backend without changing any of the front-end code?


      If so, you succeeded.






      share|improve this answer



















      • 2




        One additional suggestion: is it worth emphasizing that the goal is to achieve the goals in the bullet points with the minimal level of effort--to just hit the target and go no further? Otherwise each one of these can turn into a rabbit hole for the typical developer who (myself included) often doesn't know when to leave good-enough alone. :) And also that the only reliable way to judge success is to develop and test the API iteratively with actual users; it's impossible to guess accurately, and leads to a rabbit hole scenario of over-engineering.
        – bob
        Nov 30 at 15:48








      • 5




        I would add that, if you really do have to support multiple graphics libraries, there's almost certainly an off-the-shelf one that does everything you need to, so even then you really shouldn't roll your own. (Of course, there are exceptions, but if you're inexperienced enough to ask "how tight of an abstraction should I make" you're probably not working on a project that requires you to do it)
        – Nic Hartley
        Nov 30 at 19:27












      • I'm not a graphics dev, but looking at compatibility frameworks from the history of databases and OSes, I'd add that it's almost certainly just not worth it to make your own general framework. The framework will almost certainly have to sacrifice performance for compatibility, which probably means you can't do much with those specialized features anyway. Existing frameworks are nearly certain to handle those issues better due to wider usage. Now, if you have the massive budget you describe and want to build a specialized framework (say for one game or series), that might be more doable.
        – jpmc26
        Dec 2 at 21:18

















      up vote
      42
      down vote



      accepted










      First of all, consider if it is actually worth it to support more than one graphics API. Just using OpenGL will cover most platforms and will be "good enough" for all but the most graphically ambitious projects. Unless you work for a very large game studio which can afford to sink several thousand person-hours into implementing and testing multiple rendering backends and unless there are some DirectX or Vulcan specific features you really want to show off, it is usually not worth the hassle. Especially considering that you can save a lot of work by using an abstraction layer someone else created (a 3rd party library or game engine).



      But let's assume that you already evaluated your options and came to the conclusion that it is both viable and worth the time to roll your own.



      Then the main judge of your abstraction layer's software architecture are your front-end programmers.




      • Are they able to implement the game systems they want to implement without having to wonder about any low-level details?

      • Are they able to completely ignore that there is more than one graphics API?

      • Would it theoretically be possible to add yet another rendering backend without changing any of the front-end code?


      If so, you succeeded.






      share|improve this answer



















      • 2




        One additional suggestion: is it worth emphasizing that the goal is to achieve the goals in the bullet points with the minimal level of effort--to just hit the target and go no further? Otherwise each one of these can turn into a rabbit hole for the typical developer who (myself included) often doesn't know when to leave good-enough alone. :) And also that the only reliable way to judge success is to develop and test the API iteratively with actual users; it's impossible to guess accurately, and leads to a rabbit hole scenario of over-engineering.
        – bob
        Nov 30 at 15:48








      • 5




        I would add that, if you really do have to support multiple graphics libraries, there's almost certainly an off-the-shelf one that does everything you need to, so even then you really shouldn't roll your own. (Of course, there are exceptions, but if you're inexperienced enough to ask "how tight of an abstraction should I make" you're probably not working on a project that requires you to do it)
        – Nic Hartley
        Nov 30 at 19:27












      • I'm not a graphics dev, but looking at compatibility frameworks from the history of databases and OSes, I'd add that it's almost certainly just not worth it to make your own general framework. The framework will almost certainly have to sacrifice performance for compatibility, which probably means you can't do much with those specialized features anyway. Existing frameworks are nearly certain to handle those issues better due to wider usage. Now, if you have the massive budget you describe and want to build a specialized framework (say for one game or series), that might be more doable.
        – jpmc26
        Dec 2 at 21:18















      up vote
      42
      down vote



      accepted







      up vote
      42
      down vote



      accepted






      First of all, consider if it is actually worth it to support more than one graphics API. Just using OpenGL will cover most platforms and will be "good enough" for all but the most graphically ambitious projects. Unless you work for a very large game studio which can afford to sink several thousand person-hours into implementing and testing multiple rendering backends and unless there are some DirectX or Vulcan specific features you really want to show off, it is usually not worth the hassle. Especially considering that you can save a lot of work by using an abstraction layer someone else created (a 3rd party library or game engine).



      But let's assume that you already evaluated your options and came to the conclusion that it is both viable and worth the time to roll your own.



      Then the main judge of your abstraction layer's software architecture are your front-end programmers.




      • Are they able to implement the game systems they want to implement without having to wonder about any low-level details?

      • Are they able to completely ignore that there is more than one graphics API?

      • Would it theoretically be possible to add yet another rendering backend without changing any of the front-end code?


      If so, you succeeded.






      share|improve this answer














      First of all, consider if it is actually worth it to support more than one graphics API. Just using OpenGL will cover most platforms and will be "good enough" for all but the most graphically ambitious projects. Unless you work for a very large game studio which can afford to sink several thousand person-hours into implementing and testing multiple rendering backends and unless there are some DirectX or Vulcan specific features you really want to show off, it is usually not worth the hassle. Especially considering that you can save a lot of work by using an abstraction layer someone else created (a 3rd party library or game engine).



      But let's assume that you already evaluated your options and came to the conclusion that it is both viable and worth the time to roll your own.



      Then the main judge of your abstraction layer's software architecture are your front-end programmers.




      • Are they able to implement the game systems they want to implement without having to wonder about any low-level details?

      • Are they able to completely ignore that there is more than one graphics API?

      • Would it theoretically be possible to add yet another rendering backend without changing any of the front-end code?


      If so, you succeeded.







      share|improve this answer














      share|improve this answer



      share|improve this answer








      edited Nov 30 at 11:26

























      answered Nov 30 at 9:44









      Philipp

      76.7k19180230




      76.7k19180230








      • 2




        One additional suggestion: is it worth emphasizing that the goal is to achieve the goals in the bullet points with the minimal level of effort--to just hit the target and go no further? Otherwise each one of these can turn into a rabbit hole for the typical developer who (myself included) often doesn't know when to leave good-enough alone. :) And also that the only reliable way to judge success is to develop and test the API iteratively with actual users; it's impossible to guess accurately, and leads to a rabbit hole scenario of over-engineering.
        – bob
        Nov 30 at 15:48








      • 5




        I would add that, if you really do have to support multiple graphics libraries, there's almost certainly an off-the-shelf one that does everything you need to, so even then you really shouldn't roll your own. (Of course, there are exceptions, but if you're inexperienced enough to ask "how tight of an abstraction should I make" you're probably not working on a project that requires you to do it)
        – Nic Hartley
        Nov 30 at 19:27












      • I'm not a graphics dev, but looking at compatibility frameworks from the history of databases and OSes, I'd add that it's almost certainly just not worth it to make your own general framework. The framework will almost certainly have to sacrifice performance for compatibility, which probably means you can't do much with those specialized features anyway. Existing frameworks are nearly certain to handle those issues better due to wider usage. Now, if you have the massive budget you describe and want to build a specialized framework (say for one game or series), that might be more doable.
        – jpmc26
        Dec 2 at 21:18
















      • 2




        One additional suggestion: is it worth emphasizing that the goal is to achieve the goals in the bullet points with the minimal level of effort--to just hit the target and go no further? Otherwise each one of these can turn into a rabbit hole for the typical developer who (myself included) often doesn't know when to leave good-enough alone. :) And also that the only reliable way to judge success is to develop and test the API iteratively with actual users; it's impossible to guess accurately, and leads to a rabbit hole scenario of over-engineering.
        – bob
        Nov 30 at 15:48








      • 5




        I would add that, if you really do have to support multiple graphics libraries, there's almost certainly an off-the-shelf one that does everything you need to, so even then you really shouldn't roll your own. (Of course, there are exceptions, but if you're inexperienced enough to ask "how tight of an abstraction should I make" you're probably not working on a project that requires you to do it)
        – Nic Hartley
        Nov 30 at 19:27












      • I'm not a graphics dev, but looking at compatibility frameworks from the history of databases and OSes, I'd add that it's almost certainly just not worth it to make your own general framework. The framework will almost certainly have to sacrifice performance for compatibility, which probably means you can't do much with those specialized features anyway. Existing frameworks are nearly certain to handle those issues better due to wider usage. Now, if you have the massive budget you describe and want to build a specialized framework (say for one game or series), that might be more doable.
        – jpmc26
        Dec 2 at 21:18










      2




      2




      One additional suggestion: is it worth emphasizing that the goal is to achieve the goals in the bullet points with the minimal level of effort--to just hit the target and go no further? Otherwise each one of these can turn into a rabbit hole for the typical developer who (myself included) often doesn't know when to leave good-enough alone. :) And also that the only reliable way to judge success is to develop and test the API iteratively with actual users; it's impossible to guess accurately, and leads to a rabbit hole scenario of over-engineering.
      – bob
      Nov 30 at 15:48






      One additional suggestion: is it worth emphasizing that the goal is to achieve the goals in the bullet points with the minimal level of effort--to just hit the target and go no further? Otherwise each one of these can turn into a rabbit hole for the typical developer who (myself included) often doesn't know when to leave good-enough alone. :) And also that the only reliable way to judge success is to develop and test the API iteratively with actual users; it's impossible to guess accurately, and leads to a rabbit hole scenario of over-engineering.
      – bob
      Nov 30 at 15:48






      5




      5




      I would add that, if you really do have to support multiple graphics libraries, there's almost certainly an off-the-shelf one that does everything you need to, so even then you really shouldn't roll your own. (Of course, there are exceptions, but if you're inexperienced enough to ask "how tight of an abstraction should I make" you're probably not working on a project that requires you to do it)
      – Nic Hartley
      Nov 30 at 19:27






      I would add that, if you really do have to support multiple graphics libraries, there's almost certainly an off-the-shelf one that does everything you need to, so even then you really shouldn't roll your own. (Of course, there are exceptions, but if you're inexperienced enough to ask "how tight of an abstraction should I make" you're probably not working on a project that requires you to do it)
      – Nic Hartley
      Nov 30 at 19:27














      I'm not a graphics dev, but looking at compatibility frameworks from the history of databases and OSes, I'd add that it's almost certainly just not worth it to make your own general framework. The framework will almost certainly have to sacrifice performance for compatibility, which probably means you can't do much with those specialized features anyway. Existing frameworks are nearly certain to handle those issues better due to wider usage. Now, if you have the massive budget you describe and want to build a specialized framework (say for one game or series), that might be more doable.
      – jpmc26
      Dec 2 at 21:18






      I'm not a graphics dev, but looking at compatibility frameworks from the history of databases and OSes, I'd add that it's almost certainly just not worth it to make your own general framework. The framework will almost certainly have to sacrifice performance for compatibility, which probably means you can't do much with those specialized features anyway. Existing frameworks are nearly certain to handle those issues better due to wider usage. Now, if you have the massive budget you describe and want to build a specialized framework (say for one game or series), that might be more doable.
      – jpmc26
      Dec 2 at 21:18














      up vote
      5
      down vote













      Start by identifying what you actually need out of the "wrapper" part of the API. It's generally very, very simple: you need the basic resources (buffers, shaders, textures, pipeline state) and a way to use those resources to construct a frame by submitting some draw calls.



      Try to keep any high-level logic out of the wrapper portion of the API. If you implement a clever scene culling technique in this portion of the API, well now you are on the hook to duplicate that logic in all of the backend implementations. That's a lot of extra effort, so keep it simple. Scene management should be part of a higher-level portion of the API that uses the wrapper rather than being part of the wrapper itself.



      Choose the targets you will support and understand them. It's hard to write decent wrappers for "everything," and you probably don't need to (arguably you don't need to write a single wrapper, either, as noted in Philipp's answer). It's almost impossible to write a decent wrapper if you don't know the APIs you're going to wrap already.



      Evaluate the state of your API regularly. It should in general have a smaller surface area than the underlying wrapped APIs; if you find yourself creating one-to-one wrapper types for every D3D structure or every OpenGL function call you are probably veering off course.



      Look at what work has gone before. Sokol and BGFX are APIs that provide levels of agnosticism that may be useful to you, and are relatively easy to understand (the former especially).






      share|improve this answer

























        up vote
        5
        down vote













        Start by identifying what you actually need out of the "wrapper" part of the API. It's generally very, very simple: you need the basic resources (buffers, shaders, textures, pipeline state) and a way to use those resources to construct a frame by submitting some draw calls.



        Try to keep any high-level logic out of the wrapper portion of the API. If you implement a clever scene culling technique in this portion of the API, well now you are on the hook to duplicate that logic in all of the backend implementations. That's a lot of extra effort, so keep it simple. Scene management should be part of a higher-level portion of the API that uses the wrapper rather than being part of the wrapper itself.



        Choose the targets you will support and understand them. It's hard to write decent wrappers for "everything," and you probably don't need to (arguably you don't need to write a single wrapper, either, as noted in Philipp's answer). It's almost impossible to write a decent wrapper if you don't know the APIs you're going to wrap already.



        Evaluate the state of your API regularly. It should in general have a smaller surface area than the underlying wrapped APIs; if you find yourself creating one-to-one wrapper types for every D3D structure or every OpenGL function call you are probably veering off course.



        Look at what work has gone before. Sokol and BGFX are APIs that provide levels of agnosticism that may be useful to you, and are relatively easy to understand (the former especially).






        share|improve this answer























          up vote
          5
          down vote










          up vote
          5
          down vote









          Start by identifying what you actually need out of the "wrapper" part of the API. It's generally very, very simple: you need the basic resources (buffers, shaders, textures, pipeline state) and a way to use those resources to construct a frame by submitting some draw calls.



          Try to keep any high-level logic out of the wrapper portion of the API. If you implement a clever scene culling technique in this portion of the API, well now you are on the hook to duplicate that logic in all of the backend implementations. That's a lot of extra effort, so keep it simple. Scene management should be part of a higher-level portion of the API that uses the wrapper rather than being part of the wrapper itself.



          Choose the targets you will support and understand them. It's hard to write decent wrappers for "everything," and you probably don't need to (arguably you don't need to write a single wrapper, either, as noted in Philipp's answer). It's almost impossible to write a decent wrapper if you don't know the APIs you're going to wrap already.



          Evaluate the state of your API regularly. It should in general have a smaller surface area than the underlying wrapped APIs; if you find yourself creating one-to-one wrapper types for every D3D structure or every OpenGL function call you are probably veering off course.



          Look at what work has gone before. Sokol and BGFX are APIs that provide levels of agnosticism that may be useful to you, and are relatively easy to understand (the former especially).






          share|improve this answer












          Start by identifying what you actually need out of the "wrapper" part of the API. It's generally very, very simple: you need the basic resources (buffers, shaders, textures, pipeline state) and a way to use those resources to construct a frame by submitting some draw calls.



          Try to keep any high-level logic out of the wrapper portion of the API. If you implement a clever scene culling technique in this portion of the API, well now you are on the hook to duplicate that logic in all of the backend implementations. That's a lot of extra effort, so keep it simple. Scene management should be part of a higher-level portion of the API that uses the wrapper rather than being part of the wrapper itself.



          Choose the targets you will support and understand them. It's hard to write decent wrappers for "everything," and you probably don't need to (arguably you don't need to write a single wrapper, either, as noted in Philipp's answer). It's almost impossible to write a decent wrapper if you don't know the APIs you're going to wrap already.



          Evaluate the state of your API regularly. It should in general have a smaller surface area than the underlying wrapped APIs; if you find yourself creating one-to-one wrapper types for every D3D structure or every OpenGL function call you are probably veering off course.



          Look at what work has gone before. Sokol and BGFX are APIs that provide levels of agnosticism that may be useful to you, and are relatively easy to understand (the former especially).







          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Nov 30 at 16:43









          Josh

          91.6k16205322




          91.6k16205322






















              up vote
              2
              down vote













              Another point not yet mentioned which you should consider is what your performance goals are. If your goal is to have a graphics library that will yield good performance out of a cheap hardware platform, but also be usable on a variety of platforms that are vastly more powerful but use a different API, it may make sense to design your API around whatever abstractions are used natively on the platform where performance is an issue. Even if this causes a 50% speed degradation on the more powerful platforms, it may be worth it if it allows a 20% speed improvement on the platform where performance matters most.






              share|improve this answer

























                up vote
                2
                down vote













                Another point not yet mentioned which you should consider is what your performance goals are. If your goal is to have a graphics library that will yield good performance out of a cheap hardware platform, but also be usable on a variety of platforms that are vastly more powerful but use a different API, it may make sense to design your API around whatever abstractions are used natively on the platform where performance is an issue. Even if this causes a 50% speed degradation on the more powerful platforms, it may be worth it if it allows a 20% speed improvement on the platform where performance matters most.






                share|improve this answer























                  up vote
                  2
                  down vote










                  up vote
                  2
                  down vote









                  Another point not yet mentioned which you should consider is what your performance goals are. If your goal is to have a graphics library that will yield good performance out of a cheap hardware platform, but also be usable on a variety of platforms that are vastly more powerful but use a different API, it may make sense to design your API around whatever abstractions are used natively on the platform where performance is an issue. Even if this causes a 50% speed degradation on the more powerful platforms, it may be worth it if it allows a 20% speed improvement on the platform where performance matters most.






                  share|improve this answer












                  Another point not yet mentioned which you should consider is what your performance goals are. If your goal is to have a graphics library that will yield good performance out of a cheap hardware platform, but also be usable on a variety of platforms that are vastly more powerful but use a different API, it may make sense to design your API around whatever abstractions are used natively on the platform where performance is an issue. Even if this causes a 50% speed degradation on the more powerful platforms, it may be worth it if it allows a 20% speed improvement on the platform where performance matters most.







                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Nov 30 at 17:23









                  supercat

                  43724




                  43724






























                      draft saved

                      draft discarded




















































                      Thanks for contributing an answer to Game Development Stack Exchange!


                      • Please be sure to answer the question. Provide details and share your research!

                      But avoid



                      • Asking for help, clarification, or responding to other answers.

                      • Making statements based on opinion; back them up with references or personal experience.


                      Use MathJax to format equations. MathJax reference.


                      To learn more, see our tips on writing great answers.





                      Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


                      Please pay close attention to the following guidance:


                      • Please be sure to answer the question. Provide details and share your research!

                      But avoid



                      • Asking for help, clarification, or responding to other answers.

                      • Making statements based on opinion; back them up with references or personal experience.


                      To learn more, see our tips on writing great answers.




                      draft saved


                      draft discarded














                      StackExchange.ready(
                      function () {
                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fgamedev.stackexchange.com%2fquestions%2f165761%2fhow-do-i-know-if-im-abstracting-graphics-apis-too-tightly%23new-answer', 'question_page');
                      }
                      );

                      Post as a guest















                      Required, but never shown





















































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown

































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown







                      Popular posts from this blog

                      How to change which sound is reproduced for terminal bell?

                      Title Spacing in Bjornstrup Chapter, Removing Chapter Number From Contents

                      Can I use Tabulator js library in my java Spring + Thymeleaf project?