- 쉐이더 스토리지 블록
- 유니폼 블록과 쉐이더 스토리지 블록의 차이점
- 쉐이더가 쉐이더 스토리지 블록에 쓸 수 있다.
- 쉐이더 스토리지 공간의 멤버에 대해 어토믹 연산을 수행할 수 있다.
- 쉐이더 스토리지 블록은 크기 제한값이 훨씬 더 크다.
- std430의 새로운 패킹 규칙을 통해 데이터가 유니폼 블록보다 더 효율적으로 패킹되며 더 직접적인 접근이 가능하다.
- 사용
- 유니폼 블록을 선언하듯이 쉐이더에서 블록을 선언하면 된다.
단, uniform 키워드 대신 buffer 키워드 사용. - std140 뿐만 아니라 std430 패킹 레이아웃도 지원한다.
- 패킹 레이아웃 이름은 쉐이딩 언어 버전을 따라 지어졌다. std140은 GLSL1.40(OpenGL 3.1), std430은 GLSL 4.30(OpenGL 4.3)
- Example
- #version 430 core
- struct my_structure
- {
- int pea;
- int carrot;
- vec4 potato;
- };
- layout (binding = 0, std430) buffer my_storage_block
- {
- vec4 foo;
- vec3 bar;
- int baz[24];
- my_structure veggies;
- };
- glBufferData를 사용하여 버퍼에 데이터를 전달 할 수 있다.
- glMapBuffer를 GL_READ_ONLY로 사용하여 쉐이더에서 생산한 데이터를 읽을 수 있다.
- 버텍스 속성 대신 쉐이더 스토리지 블록 사용
- #version 430 core
- struct vertex
- {
- vec4 position;
- vec3 color;
- };
- layout (binding = 0, std430) buffer my_vertices
- {
- vertex vertices[];
- };
- uniform mat4 transform_matrix;
- out VS_OUT
- {
- vec3 color;
- };
- void main(void)
- {
- gl_Position = transform_matrix * vertices[gl_VertexID].position;
- vs_out.color = vertices[gl_VertexID].color;
- }
- 유니폼 블록이나 버텍스 속성에 비해 최적화가 어려움.
- 어토믹 메모리 연산
- 메모리 읽기와 쓰기 중간에 인터럽트가 일어나지 않아 결과가 보장되는 것
- 같은 메모리 위치의 값을 동시에 접근하여 수정하면서 충돌이 발생함.
- 어토믹 메모리 함수
int atomicAdd(
inout int mem, int data )
;uint atomicAdd(
inout uint mem, uint data )
;- mem을 읽어 data에 더한다. 결과를 mem에 쓰고, 원래 mem에 저장되어 있던 값을 리턴한다.
- atomicAnd, atomicOr, atomicXor 등
- 리턴형이 int와 unit가 있다.
- 어토믹 연산이 동일 위치에 동시에 발생하는 경우 각 호출은 직렬화 됨.
- 메모리 관련 문제
- RAW(Read-After-Write): 메모리에 쓴 다음 읽기를 시도하는 경우, 시스템에서 순서가 조정되어 쓰기가 완료되기 전에 읽기를 수행하는 경우.
- WAW(Write-After-Write): 쓰는 도중에 쓰는 경우
- WAR(Write-After-Read): 병렬 처리 시스템에서 다른 쓰레드간 동일 위치에 쓰기를 수행하는 경우.
- OpenGL의 병렬성 때문에 메모리 문제를 피하기 위한 여러가지 방법이 필요하다.
- 메모리 베리어(Memory Barrier)
void glMemoryBarrier(
GLbitfield barriers )
;- GL_ALL_BARRIER_BITS
- 모든 메모리 연산 순서를 동기화
- GL_SHADER_STORAGE_BARRIER_BIT
- 다음 쉐이더가 데이터를 액세스 하기 전에 이전 접근(쓰기)를 완료하도록 함.
- 베리어 이후에 실행하는 쉐이더는 쓰기 동작이 완료된 후의 데이터를 보게 됨.
- GL_UNIFORM_BARRIER_BIT
- 데이터를 쓴 메모리가 베리어 이후에 유니폼 버퍼로 사용되는 경우, 쓰기가 완료 될 때 까지 기다렸다가 유니폼 버퍼를 사용하도록 함.
- GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT
- 버텍스 속성을 통해 버텍스 데이터로 버퍼를 사용하기 전에 버퍼 쓰기 작업을 완료하도록 함.
- GLSL
uint memoryBarrier(
void )
;- 쉐이더 내에서 호출 시 기존에 수행했던 메모리 읽기/쓰기 동작을 완료시킴.
2018년 4월 11일 수요일
5.3 쉐이더 스토리지 블록
피드 구독하기:
댓글 (Atom)
댓글 없음:
댓글 쓰기