Кольцевая буферизованная SSBO с вычислительным шейдером - PullRequest
0 голосов
/ 30 декабря 2018

Я выполняю выборку усеченного вида и генерирую команды рисования на GPU в вычислительном шейдере, и я хочу передать ограничивающие тома в SSBO.В настоящее время я использую только большой однородный массив, но я хочу увеличить его, поэтому необходимо перейти на SSBO.

То, чего я хочу достичь, - это нечто вроде подхода AZDO к использованию тройной буферизации, чтобы избежать проблем с синхронизацией при обновлении SSBO, обновляя только одну треть буфера, защищая остальные с помощью ограждений.

Можно ли это объединить с диспетчеризацией вычислительного шейдера или я должен просто создать три разных SSBO и затем связать каждый из них соответственно?

Решение, как я сейчас вижу, состоит в том, чтобы как-то сообщитьследующий откат для выборки данных в SSBO только с определенного смещения (0 * buffer_size, 1 * buffer_size и т. д.).Это вообще возможно?

Цикл рендеринга

  /* Fence creation omitted for clarity */

  // Cycle round updating different parts of the buffer
  const uint32_t buffer_idx = (frame % gl_state.bvb_num_partitions);
  uint8_t* ptr = (uint8_t*)gl_state.bvbp + buffer_idx * gl_state.bvb_buffer_size;
  std::memcpy(ptr, bounding_volumes.data(), gl_state.bvb_buffer_size);
  const uint32_t gl_bv_binding_point = 3; // Shader hard coded
  const uint32_t offset = buffer_idx * gl_state.bvb_buffer_size;
  glBindBufferRange(GL_SHADER_STORAGE_BUFFER, gl_bv_binding_point, gl_state.bvb, offset, gl_state.bvb_buffer_size);

  // OLD WAY: glUniform4fv(glGetUniformLocation(gl_state.cull_shader.gl_program, "spheres"), NUM_OBJECTS, &bounding_volumes[0].pos.x);

  glUniform4fv(glGetUniformLocation(gl_state.cull_shader.gl_program, "frustum_planes"), 6, glm::value_ptr(frustum[0]));

  glDispatchCompute(NUM_OBJECTS, 1, 1);

  glMemoryBarrier(GL_COMMAND_BARRIER_BIT | GL_SHADER_STORAGE_BARRIER_BIT); // Buffer objects affected by this bit are derived from the GL_DRAW_INDIRECT_BUFFER binding. 

Создание ограниченного объема SSBO

// Bounding volume buffer
glGenBuffers(1, &gl_state.bvb);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, gl_state.bvb);
gl_state.bvb_buffer_size = NUM_OBJECTS * sizeof(BoundingVolume);
gl_state.bvb_num_partitions = 3; // 1 for application, 1 for OpenGL driver, 1 for GPU
GLbitfield flags = GL_MAP_COHERENT_BIT | GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT;
glBufferStorage(GL_SHADER_STORAGE_BUFFER, gl_state.bvb_num_partitions * gl_state.bvb_buffer_size, nullptr, flags);
gl_state.bvbp = glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, gl_state.bvb_buffer_size * gl_state.bvb_num_partitions, flags);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...