Viết vào một kết cấu nén bằng cách sử dụng một shader tính toán, không có bản sao bổ sung


8

Tôi đang cố gắng tìm ra cách tốt nhất để tạo ra kết cấu OpenGL bằng cách sử dụng trình đổ bóng tính toán. Cho đến nay, tôi đã đọc được rằng các đối tượng bộ đệm pixel rất tốt cho CPU không chặn -> truyền GPU và các shader tính toán có khả năng đọc và ghi bộ đệm bất kể chúng bị ràng buộc như thế nào. Lý tưởng nhất là tôi muốn tránh càng nhiều bản sao càng tốt. Nói cách khác, tôi muốn phân bổ bộ đệm trên GPU, ghi dữ liệu kết cấu nén vào nó và sau đó sử dụng bộ đệm đó làm đối tượng kết cấu trong trình đổ bóng.

Hiện tại, mã của tôi trông giống như thế này:

GLuint buffer;
glGenBuffers(1, &buffer);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, buffer);
glBufferStorage(GL_SHADER_STORAGE_BUFFER, tex_size_in_bytes, 0, 0);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);

// Bind buffer to resource in compute shader
// execute compute shader

glBindBuffer(GL_PIXEL_UNPACK_BUFFER, buffer);
glCompressedTexImage2D(GL_TEXTURE_2D, 0, fmt, w, h, 0, tex_size_in_bytes, 0);

Điều này có đúng không? Tôi cũng đọc ở đâu đó về việc đảm bảo đồng bộ hóa. Tôi cần thêm gì để đảm bảo rằng trình đổ bóng tính toán của tôi hoàn thành việc thực thi trước khi sao chép từ đối tượng bộ đệm?


Bạn có muốn chỉ định định dạng nén kết cấu nào bạn thích? Tôi đoán nhưng câu trả lời của bạn có thể sẽ liên quan đến thói quen nén kết cấu chế độ tính toán.
ap_

Câu trả lời:


3

Sau khi xem xét điều này một lúc, tôi phát hiện ra một vài điều:

  1. Bạn không thể tránh một memcpy : Bạn không thể ghi trực tiếp vào bộ lưu trữ kết cấu được phân bổ cho kết cấu được nén chỉ bằng các lệnh gọi API OpenGL. Điều này có nghĩa là bạn không thể tránh cuộc gọi đến glCompressedTexImage2Dvới PBO bị ràng buộc. Điều đó đang được nói, bạn có thể sử dụng kết cấu RGBA 16 bit và loại hình ảnh GLSL trong trình đổ bóng tính toán của bạn.

  2. Bạn cần phải đồng bộ hóa bộ nhớ : Để đảm bảo rằng trình đổ bóng tính toán của bạn kết thúc việc ghi vào bộ đệm lưu trữ của bạn, bạn phải đảm bảo rằng tất cả các lần đọc và ghi vào nó kết thúc. Điều này được thực hiện bằng cách gọi glMemoryBarriervới GL_SHADER_STORAGE_BARRIER_BIT.

Mã đầy đủ cho một cái gì đó ghi vào bộ đệm được sử dụng làm kết cấu nén trông như thế này:

GLuint buffer;
glGenBuffers(1, &buffer);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, buffer);
glBufferStorage(GL_SHADER_STORAGE_BUFFER, tex_size_in_bytes, 0, 0);

glUseProgram(compute_shader_prog);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, compute_shader_bind_point, buffer);
glDispatchCompute(wg_x, wg_y, wg_z);
glMemoryBarrier(GL_SHADER_STORAGE_BUFFER_BIT);

glBindBuffer(GL_PIXEL_UNPACK_BUFFER, buffer);
glCompressedTexImage2D(GL_TEXTURE_2D, 0, fmt, w, h, 0, tex_size_in_bytes, 0);

"Bạn có thể sử dụng kết cấu RGBA 16 bit và" VÀ CÁI GÌ ??? :)
Nathan Reed

2
Haha, đây là những gì xảy ra khi bạn để tab mở để hoàn thành sau này. Đã chỉnh sửa.
Mokosha

1
GL_SHADER_STORAGE_BARRIER_BITSai rào cản. Rào cản bạn cung cấp cho biết cách bạn sẽ sử dụng bộ nhớ. Không phải làm thế nào các shader đã viết cho nó. Bạn đang thực hiện chuyển pixel, vì vậy bạn cần sử dụngGL_TEXTURE_UPDATE_BARRIER_BIT
Nicol Bolas

1
Bạn có chắc không? Theo các tài liệu , GL_TEXTURE_UPDATE_BARRIER_BITđược sử dụng khi đồng bộ hóa các cuộc gọi đến glTexImagevà không liên quan gì đến bộ nhớ được sử dụng trong bộ đệm lưu trữ. Tôi nghĩ bạn có ý GL_PIXEL_BUFFER_BARRIER_BITgì?
Mokosha
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.