🎉 Celebrating 25 Years of GameDev.net! 🎉

Not many can claim 25 years on the Internet! Join us in celebrating this milestone. Learn more about our history, and thank you for being a part of our community!

OpenGL share GL_RENDERBUFFER between threads

Started by
1 comment, last by JohnnyCode 3 years, 11 months ago

Dear GameDEV,

Forgive me if this has been answered too many times, I went through about 4 pages of results (here and Google) and none have helped with this question (at least to my current knowledge base)...

I currently have 2 threads (2 contexts) in OpenGL; one to render the frame and one to render all the 2D ontop of the frame (labeled HUD). While this works I can see a significant performance loss rendering the HUD as 1920x1080 vs 1440x810 (witch I know is ~3.5MB difference)

Partial Code:

Renderer:

while((getState()) != STATE_SHUTDOWN) {
	glClearColor(0.0, 0.0, 0.0, 1.0);
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	// RENDER LOOP STUFF
	// ...
	
	// Display HUD
	glClear(GL_DEPTH_BUFFER_BIT);
	uint32_t *HUDTex = getHUD();
	glBindTexture(GL_TEXTURE_2D, HUD_TEX);
	if(HUDTex) {
		glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, HUDx, HUDy, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, HUDTex);
		glGenerateMipmap(GL_TEXTURE_2D);
	}
	glProgramUniformMatrix4fv(ProgramID, glGetUniformLocation(ProgramID, "MVP"), 1, GL_FALSE, HUD_MVP);
	glBindVertexArray(HUD_VAO);
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, HUD_EBO);
	glDrawElements(GL_TRIANGLES, HUD_ElementsCount, GL_UNSIGNED_INT, NULL);
}

HUD:

while((getState()) != STATE_SHUTDOWN) {
	if(HUD_Updated) {
		glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer);
		glClearColor(0.0, 0.0, 0.0, 0.0);
		glClear(GL_COLOR_BUFFER_BIT);
		// RENDER LOOP STUFF
		Menu_draw();
		Cursor_draw();
		Crosshair_draw();
		UI_draw();
		// ...
		glReadPixels(0, 0, HUD_Width, HUD_Height, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, HUD_Buffer);
	}
	// ...
}

My main question is how to share this 2D rendered “texture” with the main thread without having to rely on GPU→CPU→GPU bandwidth?

Both these threads are currently under different contexts (and windows) and would really love to find a way to share the GPU memory where these are located instead of relying on the CPU to copy out of GPU and back into GPU memory.

I really want to be able to not just separate the HUD from the main thread, but also the “Map” from the main thread (with depth mapping).

Sincerely,

THoover

EDIT:

To add a little more detail, the HUD initialization is as follows:

HUD_Buffer = calloc(HUD_Width * HUD_Width, sizeof(uint32_t));
glGenFramebuffers(1, &frameBuffer);
glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer);
GLuint texColorBuffer;
glGenTextures(1, &texColorBuffer);
glBindTexture(GL_TEXTURE_2D, texColorBuffer);

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, HUD_Width, HUD_Height, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, NULL);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texColorBuffer, 0);
GLuint rboDepthStencil;
glGenRenderbuffers(1, &rboDepthStencil);
glBindRenderbuffer(GL_RENDERBUFFER, rboDepthStencil);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, HUD_Width, HUD_Width);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rboDepthStencil);
GLuint renderbuf;
glGenRenderbuffers(1, &renderbuf);
glBindRenderbuffer(GL_RENDERBUFFER, renderbuf);
glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, HUD_Width, HUD_Width);
glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, renderbuf);
Advertisement

GPU dispatching of calls can be multithreaded without a reason to share GPU objects data such as render buffers. But you have 2 different contexts, you cannot batch them together as by picking what to share and what not.

This topic is closed to new replies.

Advertisement