2017-02-10 12 views
1

필자는 펜 타블렛 입력을 듣고 버텍스/인덱스 버퍼 (다른 것들 중에서)에서 그려주는 렌더링 루프를 가지고 있습니다. 정점 데이터는 성장할 수 있으며 특정 레벨에 도달 할 때, DispatchMsg (& MSG)이 발생 :DirectX11 비디오 메모리 초과

장면에서 할당 된 버텍스와 인덱스 버퍼의 전체 크기는 동일 수준의 주위에 때마다 있습니다
Unhandled exception at 0x5DDBDEF0 (msvcr110d.dll) in App.exe: 0xC0000005: Access violation writing location 0x00000000. 

:

Total Vertices count: 10391370 
Total Indices count: 41565480 
Total Vertices size: 249392880 (bytes) 
Total Indices size: 997571520 (bytes) 

다른 샘플링에 :

Total Vertices count: 9969300 
Total Indices count: 39877200 
Total Vert size: 239263200 
Total Indices size: 957052800 

정점 색인 버퍼 모두 D3D11_USAGE_DEFAULT이다. 장면의 전체 크기 할당은 위에 나열된 것보다 높지만 더 작은 버퍼는 자주 릴리스됩니다. 끝 부분의 정점/인덱스 버퍼에도 약간의 패딩이 있습니다.

내가 믿는 (예외가 도달 할 때)마다 파견 581입니다 될에 대한 메시지가 될 수있다 : 나는 경우

#define WM_POINTERUPDATE    0x0245 

난 정말 천천히 렌더링 장면을 상관하지 않지만 몇 가지 최대 메모리 할당 (비디오 메모리?)에 도달하는 방법은 메모리를 천천히 페이지 메모리를 /에서 속도의 비용으로 마임? draw() 호출을 비활성화하여 픽셀, 정점 셰이더 및 드로잉 호출을 시도했지만 예외가 여전히 발생합니다. 나는 속도를 상쇄하거나 예외적 인 해결 방법을 선호한다.

+0

몇개의 지형을 그리나요? 그것은 많은 데이터처럼 보입니다. 천만 달러? – tadman

+0

정확합니다. 문제가 발생할 것으로 예상됩니다. 이유를 파악하거나 문제를 해결할 수 있습니다. – user176692

+0

그것은 많은 verts입니다. 무언가없이 불을 끄는 많은 것들을 할당 할 수있어서 놀랍습니다. 어떻게 든 누출하는 것처럼 너무 많은 것을 만들고 있습니까? – tadman

답변

1

귀하의 질문에있는 숫자를 보면 정점 및 색인 데이터 (약 1.2GB)에 많은 메모리를 할당하고있는 것으로 보입니다. 앱이 32 비트 (x86, x64와 반대) 인 경우 2GB의 메모리에만 액세스 할 수 있으므로 프로세스가 메모리 부족 상태 일 수 있습니다.

GPU는 시스템 메모리의 일부에 액세스 할 수 있습니다 (GPU 메모리에 비해 속도는 매우 느리지 만 메모리가없는 것보다 낫습니다). 예를 들어, NVidia GPU의 경우 NVidia 제어판에 "시스템 정보"> "공유 시스템 메모리"에 표시됩니다. 이것은 대개 시스템의 총 RAM 용량의 절반입니다.내가 아는 한이 시스템 메모리는 프로세스의 주소 공간을 차지합니다.

"꽤 오래된"GPU에 512MB 메모리가있는 경우 메모리 요청을 충족시키기 위해 약 768MB의 추가 시스템 메모리가 필요합니다. 이것은 응용 프로그램에 1.2GB를 남겨 둡니다. 귀하의 응용 프로그램은 GPU에 업로드하려는 지오메트리 데이터를 가져올 배열에 1.2GB의 시스템 메모리를 할당하려고합니다. 이것은 맞을 지 모르겠지만 애플리케이션 코드는 어딘가에 있어야합니다. 이 가상의 경우 이미 메모리가 부족합니다. 물론 Geometry 데이터를 GPU에 업로드 한 후에는 시스템 메모리 배열을 제거 할 수 있지만이 순간에는 시스템에서 요청한 크기의 GPU 메모리 버퍼를 만들 충분한 메모리가 없습니다 .

프로젝트를 64 비트 (Visual Studio의 x64)로 전환하면 프로세스가 훨씬 더 많은 메모리 (대부분의 경우 시스템과 페이지 파일에서 사용 가능한 것까지)를 차지하고 문제를 해결할 수 있습니다. 메모리 제약이 실제로 문제가되는 경우.

또 다른 사실 : 숫자가 맞다고 가정하면 인덱스 버퍼에 대해 인덱스 당 24 바이트를 할당합니다. 정점 버퍼의 각 정점에 할당하는 것과 같습니다. 그 맞습니까? 인덱스 (정점 버퍼에의 오프셋)는 4 바이트보다 커야합니다. 실제로 필요한 것보다 6 배 많은 GPU 메모리를 할당하려고합니까? 아니면 응용 프로그램에서 잘못 계산 한 것입니까?

GPU에서 버퍼를 신속하게 해제했다가 다시 만들면 D3D는 "오래된"버퍼를 잠시 동안 유지합니다 (적어도 GPU 파이프 라인에 여전히 바인딩되어있는 한). 그것으로 인해 추억이 되십시오. 따라서 실제로 해제 할 버퍼의 연결을 해제하는 것이 도움이 될 수 있습니다 (IASetVertexBuffers(NULL, 0, 0, 0, 0)IASetIndexBuffer(NULL, DXGI_FORMAT_R16_UINT, 0) 호출).

+0

인덱스 할당은 꺼져 있었을 수도 있지만 각 꼭지점은 피라미드 또는 다이아몬드 유형의 모양을 만들기 위해 다시 사용되었습니다. 실시간 렌더링을위한 제어점 및 테셀레이션 또는 지오메트리 셰이더, 오프라인 렌더링을위한 영역으로 대체되고 있습니다. 32 비트 주소 공간은 큰 문제입니다. 언급 해 주셔서 감사합니다. 나는 그것을 간과했습니다. 필자가 만든 32 비트 라이브러리를 사용 중이며이를 포팅해야합니다. 또한 W5100 Firepro를 사용하면 메모리 기능을 확장 할 수 있습니다. – user176692

+0

너무 명확한 인덱스의 수 (재사용 인덱스 FTW)가 아니라 인덱스가 차지하는 메모리 (바이트 수)입니다. 첫 번째 예제의 41565480 색인은 41565480 * 4 = 166261920 바이트 (166MB)를 차지하지만, 질문에 따르면 997571520 바이트 (997MB!)가 할당되어 32 비트 프로세스의 메모리 제한을 거의 지나치게 사용하게됩니다 . 명시된 메모리의 양이 인덱스의 수에 24 (정점 크기)를 곱한 값이기 때문에 인덱스 버퍼 크기 계산 또는 오타에 오류가있을 수 있습니다. – Pepor

+0

나는 그렇게 생각한다! 이것이 주석 처리되었지만 debugMsg ("Ind size :"+ iToS (sizeof (Vertex) * editingModel-> builtIndicesCount))를 사용하고있는 디버그 메시지를 확인하지 못했습니다. 따라서 디버그 로그에 잘못 표시되는 것보다 할당량이 적습니다.이미 제어점을 사용하고 형상이 작성되는 방식을 변경하지만 좋은 캐치! – user176692

1

답을 찾은 다음 문제가 해결되었습니다. 입력 버텍스 수에 따라 CreateBuffer가 실패하거나 malloc/HeapAlloc이 실패했습니다.

GPU가 특정 지점 이후에 메인 시스템 메모리로 페이징 메모리를 사용해야하는 경우 또는 각 프레임의 계산 중 장면 데이터가 GPU 메모리에 남아 있어야하기 때문에 피할 수없는 경우 (깊이, 조명 , etc.),하지만 내가 수동으로 dealloc'ed/realloc'ed 버퍼 (어쨌든 느린 것입니다) 및 B) alloc'ed 버퍼 (정점, 인덱스 ..)의 크기를 경우에만 페이징이 가능할 것이라고 생각 문제가 아니라 프레임 당 계산

다른 버퍼 사용 (USAGE_DYNAMIC)으로 전환하려고 시도했지만 할당 실패가 여전히 같은 수준에서 발생했습니다.

저는 버퍼 크기 (패딩이 필요한 버퍼)를 빠르게 변경했고 적어도 2,000 만개의 꼭지점을 사용했습니다. 내 GPU는 꽤 오래되었으므로 그렇게 나쁘지는 않습니다. 일부 렌더러는 이걸 넘어서도 잘 할 수 있습니다.

해결 방법에 초점을 맞추고 가능한 경우 세부 정보를 줄이려고합니다. 나는 tesselation으로 15 배 더 세부적인 것을 얻을 수 있다고 생각합니다. 나쁜 모양이 아닙니다.

더 많은 통찰력을 갖고있는 사용자는 답을 올바른 것으로 전환 할 수 있지만 여기에 다른 경로를 선택할지 확실하지 않습니다.