Menulis ke tekstur terkompresi menggunakan penghitung komputasi, tanpa salinan tambahan

8

Saya mencoba mencari tahu apa cara terbaik untuk menghasilkan tekstur OpenGL menggunakan compute shader. Sejauh ini, saya telah membaca bahwa objek penyangga piksel baik untuk CPU non-blocking -> transfer GPU, dan penghitung komputasi mampu membaca dan menulis buffer terlepas dari bagaimana mereka terikat. Idealnya, saya ingin menghindari salinan sebanyak mungkin. Dengan kata lain, saya ingin mengalokasikan buffer pada GPU, menulis data tekstur terkompresi, dan kemudian menggunakan buffer itu sebagai objek tekstur dalam shader.

Saat ini, kode saya terlihat seperti ini:

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);

Apakah ini benar? Saya membaca di suatu tempat tentang jaminan sinkronisasi. Apa yang perlu saya tambahkan untuk memastikan bahwa penghitung shader saya menyelesaikan eksekusi sebelum menyalin dari objek buffer?

Mokosha
sumber
Apakah Anda ingin menentukan format kompresi tekstur yang Anda sukai? Saya menebak tetapi jawaban Anda kemungkinan akan melibatkan rutin kompresi tekstur mode-komputasi.
ap_

Jawaban:

3

Setelah melihat ini sebentar, saya menemukan beberapa hal:

  1. Anda tidak dapat menghindari memcpy : Anda tidak dapat menulis langsung ke penyimpanan tekstur yang dialokasikan untuk tekstur terkompresi hanya menggunakan panggilan OpenGL API. Ini berarti bahwa Anda tidak dapat menghindari panggilan ke glCompressedTexImage2Ddengan PBO terikat. Yang sedang berkata, Anda mungkin dapat menggunakan tekstur RGBA 16-bit dan tipe gambar GLSL dalam penghitung komputasi Anda.

  2. Anda perlu menyinkronkan memori : Untuk memastikan bahwa penghitung komputasi Anda selesai menulis ke buffer penyimpanan Anda, Anda harus memastikan bahwa semua membaca dan menulis selesai. Ini dilakukan dengan menelepon glMemoryBarrierdengan GL_SHADER_STORAGE_BARRIER_BIT.

Kode lengkap untuk sesuatu yang menulis ke buffer untuk digunakan sebagai tekstur terkompresi terlihat seperti ini:

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);
Mokosha
sumber
"Anda mungkin dapat menggunakan tekstur RGBA 16-bit dan" DAN APA ??? :)
Nathan Reed
2
Haha, inilah yang terjadi ketika Anda membiarkan tab terbuka untuk menyelesaikan nanti. Diedit.
Mokosha
1
GL_SHADER_STORAGE_BARRIER_BITPenghalang salah. Penghalang yang Anda berikan menyatakan bagaimana Anda akan menggunakan memori. Tidak bagaimana shader menulisnya. Anda sedang melakukan transfer piksel, jadi Anda perlu menggunakanGL_TEXTURE_UPDATE_BARRIER_BIT
Nicol Bolas
1
Apakah kamu yakin Menurut dokumen , GL_TEXTURE_UPDATE_BARRIER_BITdigunakan saat menyinkronkan panggilan glTexImage, dan tidak ada hubungannya dengan memori yang digunakan dalam buffer penyimpanan. Saya pikir Anda maksud GL_PIXEL_BUFFER_BARRIER_BIT?
Mokosha