IDirect3DDevice9::CreateTexture

작성자

카테고리:

D3DUSAGE
http://telnet.or.kr/directx/graphics/reference/d3d/constants/d3dusage.htm
////////////////////////////////////////////////////////////////////////////////

D3DPOOL 열거형
http://telnet.or.kr/directx/graphics/reference/d3d/enums/d3dpool.htm
////////////////////////////////////////////////////////////////////////////////

http://gpgstudy.com/forum/viewtopic.php?t=8829&highlight=%C6%C4%C6%BC%C5%AC+%C1%A4%B7%C4

SDK 도움말에 설명이 나와있긴하지만.. 그래도 꽤 많은 분들이 헷갈려하시는거 같습니다.

D3DPOOL_MANAGED 는 풀이 시스템메모리에 백업되고 필요시에 비디오메모리로 로드됩니다. 한번 로드된 풀은 해제되거나 아니면 메모리의 부족으로 강제로 내려갈때까진 메모리상에서 유효합니다.
시스템메모리에 백업되어있기때문에 디바이스 리셋시에도 별다른 조치를 할 필요가 없습니다.

D3DPOOL_DEFAULT 는 풀이 비디오메모리에 바로 생성되고 메모리가 부족하면 풀을 만들때 오류를 뱉어냅니다. 따로 백업되어있지않기때문에 디바이스 리셋시에 더이상 유효하지 않게 됩니다.

D3DPOOL_MANAGED 는 시스템메모리에 백업되어있기때문에 ‘Read’ 하는것에는 별다른 문제가 없습니다. 다만 ‘Write’ 는 하게될때마다 메모리에서 내렸다가 다시 로드되어야되기때문에 무리가 따릅니다. (레퍼런스상에서도 D3DPOOL_MANAGED 로 생성된 버텍스버퍼나 인덱스버퍼는 런타임상에서 업데이트하는걸 성능상에 문제로 추천하고 있지 않습니다. 같은 이유로 렌더타겟같은것들은 D3DPOOL_MANAGED 로 만들수가 없습니다.)

D3DPOOL_DEFAULT 는 따로 시스템메모리에 백업이 없기때문에 ‘Read’ 에 무리가 있습니다. 다만 ‘Write’ 하는것에는 D3DPOOL_MANAGED 로 만들어진것보단 적합해서 각종 다이나믹 버텍스버퍼/인덱스버퍼 등에 쓰이게 됩니다.

다이나믹 버텍스버퍼나 인덱스버퍼를 쓸때 자주 쓰이는 옵션인 D3DLOCK_DISCARD 와D3DLOCK_NOOVERWRITE 는 CPU 와 GPU 의 병목현상을 막기위한 플래그들입니다.
D3DLOCK_DISCARD 는 현재 드라이버가 잡고있는 풀은 그대로 내버려두고 같은 크기의 새로운 풀을 잡아서 거기에 업데이트를 할수 있게합니다. 그리고 잡고있던 풀이 다 쓰여지고 나면 그 풀을 해제되고 새롭게 만들어졌던 풀이 쓰이게 되는거죠. 드라이버가 다 그릴때까지 멈춰있을수없으니 이런식으로 쓰게 됩니다.
D3DLOCK_NOOVERWRITE 는 현재드라이버가 잡고있는 풀을 업데이트하지 않겠다고 명시적으로 말하는거가 되겠네요. 렌퍼런스에서는 저 두개의 옵션중에 한가지는 꼭 Lock 할때 써주는것을 추천하고 있습니다. (두개같이 쓰는건 비추하고 있습니다.)

이런저런 이유로 보통 다이나믹 버텍스버퍼나 인덱스버퍼를 쓸때는 조금 큰 하나의 풀을 잡아놓고 거기에 조금씩 알맞는 플래그로 업데이트해가며 렌더링하는게 여러가지면에서 좋은거 같습니다.

unsigned int uOffset = 0;
Loop {
unsigned int uVertexSize = …;
if(uOffset+uVertexSize > uVertexBufferSize) {
uOffset = 0;
}
unsigned long dwLockFlag = D3DLOCK_DISCARD;
if(uOffset > 0) dwLockFlag = D3DLOCK_NOOVERWRITE;
pVertexBuffer->Lock(uOffset, uVertexSize, …, dwLockFlag);

pVertexBuffer->Unlock();
DrawPrimitive(…);
uOffset += uVertexSize;
}

1.
D3DPOOL_MANAGED 나 D3DPOOL_DEFAULT 나 업데이트를 하지 않는다는 조건에서는 성능은 같습니다. (다만 D3DPOOL_MANAGED 로 생성된 많은양의 풀들이 한꺼번에 비디오메모리로 로드되는 순간에는 버벅임같은것을 느낄수는 있습니다.)
2.
D3DPOOL_MANAGED 로 생성된 풀을 런타임상에서 계속 Lock/Unlock 하는건 DrawPrimitiveUP 보다 더 느릴수도 있습니다.
3.
모두 D3DPOOL_DEFAULT 로 바꾼다면 비디오메모리가 부족하면 아예 풀생성 자체가 안됩니다. 용도에 따라 꼭 D3DPOOL_MANAGED 가 되어야되는경우도 있습니다. (텍스쳐같은걸 Lock/Unlock 등을 통해서 읽어야되는경우) 레퍼런스상에서는 특별한 경우를 제외하곤 D3DPOOL_MANAGED 를 쓰라고 하고 있습니다.