Fixing buffer_set_surface in GameMaker: Studio

If you are still using GameMaker: Studio instead of moving to a more current version (perhaps you should - it's been almost five years since GMS1 support has ended) and you are doing extension work or anything else that demands conversions between raw pixel data and surfaces on Windows, you might have noticed that buffer_set_surface doesn't work on some computers - no matter what you pass in, no pixels appear on the surface.

Though the better way to put it would be "buffer_set_surface doesn't work anymore".

This is a post about the matter.

The issue

Once upon a time, I filed a bug report about buffer_set_surface not working on Intel GPUs (while working fine on an NVIDIA GPU). The report was later closed due to likely being a driver bug.

Imagine my surprise when I ran the same code on the same GameMaker: Studio version half a decade later and found that it now doesn't work on NVIDIA GPUs either... but it still works on AMD! And in WINE. And on any GPU in GMS2 (which uses D3D11 instead of D3D9).

Is this a bug in two drivers?

The fix

Without getting into D3D9 trickery, the most obvious alternative is to simply plot the pixels into the surface.

You can do this in GML itself, but that can get a little slow due to dynamic nature of the language, so a better alternative is to utilize a trick from a few years back to call a built-in function from C++ code.

Caveats

  • For reasons perhaps related to CPU caching, the function starts working a bunch faster after the first few times you call it.
  • The fallback function calls draw_set_blend_mode_ext and then sets it back to draw_set_blend_mode(bm_normal), which is a thing to keep in mind if you use the function amid blend mode manipulations for some reason.

And that's all. You can find the compiled extension on itch and source code on GitHub.

Download Source code

Related posts:

One thought on “Fixing buffer_set_surface in GameMaker: Studio

  1. what are the odds, i was having this exact issue and you made this just a few days ago !
    thank you !

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.