2

I've been working on a Game Boy emulator using Qt and OpenGL. I'm pretty new to both Qt and OpenGL. It's in a pretty stable condition, and I removed what I thought was some wasteful code from the OpenGL routines. I have a routine that is called roughly 60 times every second by a Qt signal to update the OpenGL texture for the emulated screen. I changed this to just setting the texture's data with the new screen buffer. The problem I ran into is that leaving the wasteful code that destroys and creates a new texture somehow runs faster than just setting the new data. This is what I have:

void OpenGlWidget::updateEmulatedScreen(uint32_t *screenData) {
    emulatedScreenTexture->destroy();
    emulatedScreenTexture->create();
    emulatedScreenTexture->setFormat(QOpenGLTexture::RGBA8_UNorm);
    emulatedScreenTexture->setSize(EMULATED_SCREEN_RESOLUTION_X, EMULATED_SCREEN_RESOLUTION_Y);
    emulatedScreenTexture->setMinMagFilters(QOpenGLTexture::Nearest, QOpenGLTexture::Nearest);
    emulatedScreenTexture->setWrapMode(QOpenGLTexture::ClampToEdge);
    emulatedScreenTexture->allocateStorage();

    emulatedScreenTexture->setData(QOpenGLTexture::PixelFormat::RGBA, QOpenGLTexture::PixelType::UInt32_RGBA8, screenData);
    this->update();
}

I changed it to this:

void OpenGlWidget::updateEmulatedScreen(uint32_t *screenData) {
    emulatedScreenTexture->setData(QOpenGLTexture::PixelFormat::RGBA, QOpenGLTexture::PixelType::UInt32_RGBA8, screenData);
    this->update();
}

To me, this seems a lot more efficient than destroying and creating a new texture each time, but it somehow slows the emulation down tremendously. I've tested multiple times without changing anything else, and adding the destroy/create speeds it back up every time. Am I missing something? Is it actually somehow worse to just set the data each time?

  • Modifying the image data of an existing texture may result in concurrent access from CPU and GPU to the same texture. Hence, that may stall the GPU work. Creating a new texture appears to be much more effort but it doesn't prevent the oneway pipe-lining from CPU to GPU. Once a texture is created it is accessed by the GPU exclusively, and CPU and GPU can work concurrently. But, this is just my shot into blue based on my limited understanding... ;-) – Scheff's Cat Apr 10 '21 at 08:53
  • FYI: [SO: Updating a texture in OpenGL with glTexImage2D](https://stackoverflow.com/a/13248668/7478597), [SO: How to manipulate texture content on the fly?](https://stackoverflow.com/a/10702468/7478597) – Scheff's Cat Apr 10 '21 at 08:55
  • FYI: [SO: Efficient way of updating texture in OpenGL](https://stackoverflow.com/a/21578261/7478597) (It seems my "shot into blue" was not that bad that I was afraid of...) ;-) – Scheff's Cat Apr 10 '21 at 09:00
  • Oh, I see. So, basically when I set the data of the old texture, OpenGL is probably still drawing it to the screen while I'm trying to change its data. So, the program just sits there. If I create a new one, it's not blocked because its a different texture as far as OpenGL is concerned even though it's the same object to Qt. – Benjamin Crew Apr 10 '21 at 09:07

0 Answers0