728x90

가상 그래픽 드라이버 외주 개발자가 만들어준 드라이버가 SwDeviceCreate()와 SwDeviceClose()를 호출하다가 일정 횟수를 반복하다보면 그래픽 드라이버가 제대로 만들어지지 않는 현상을 발견하였다.

Debuging을 해보니 DirectX 자원을 생성하려고 할때 E_OUTOFMEMORY 가 발생하는거였다.

하지만 이것도 IGPU, AMD는 괜찮지만 NVIDIA에서만 발생한다.

그래서 NVIDIA Memory leak을 검색하다보니 flush()를 하면 괜찮다는 글을 발견하였다.

그렇다면 DX Resource를 Release할 때 AMD와 IGPU는 바로 해제를 하지만 NVIDIA는 Flush가 발생할때까지 command list에 쌓아두기만하다가 한번에 처리하는건 아닐까? 생각이 든다.

 

참조 : https://forums.developer.nvidia.com/t/create-texture-cause-memory-leak/50121

 

create texture cause memory leak

Repeat to create texture and release, it will lead to a memory leak. https://devtalk.nvidia.com/default/topic/911464/graphic-driver-memory-leak/#4784574 #include "stdafx.h" #include <direct.h> #include <dxgi.h> #include <d3d11.h> #include <stdio.h> #includ

forums.developer.nvidia.com

 

참조 : https://stackoverflow.com/questions/58726052/directx-11-createvertexshader-memory-leak

 

728x90
728x90

D3D11_TEXTURE2D_DESC 구조체

2차원 텍스처에 대한 정보를 서술하는 구조체

 

 멤버 변수

 설명 

 Width

 2차원 텍스처의 가로 크기 ( 텍셀 단위 )

 Height

 2차원 텍스처의 세로 크기 ( 텍셀 단위 )

 MipLevels

 최대 밉맵 레벨

 다중 샘플링 텍스처는 1을 사용하며 0을 사용하면 가능한 최대 밉맵 레벨을 설정한다.

 ArraySize

 텍스처 배열의 텍스처 개수

 Format

 텍스처의 텍셀 데이터 형식

 SampleDesc

 다중 샘플링 정보를 나타내는 구조체

 Usage

 텍스처를 어떻게 읽고 쓸 것인지를 나타내는 D3D11_USAGE 열거형 상수

 보통 D3D11_USAGE_DEFAULT 를 사용한다

 BindFlags

 텍스처를 파이프라인 단계에 어떻게 연결할 것인가를 나타내는 D3D11_BIND_FLAG 열거형 상수

 CPUAccessFlags

 허용되는 CPU 접근 권한을 나타내는 D3D11_CPU_ACCESS_FLAG 열거형 상수

 0을 사용하면 CPU가 이 텍스처에 접근할 필요가 없다는 의미

 MiscFlags

 D3D11_RESOURCE_MISC_FLAG 열거형 상수

 보통 0을 사용한다.

 


ID3D11Device::CreateTexture2D() 함수

2차원 텍스처 리소스를 생성하는 함수

2차원 텍스처 리소스는 여러 개의 2차원 서브 리소스를 포함 할 수 있다.

서브 리소스의 개수는 D3D11_TEXTURE2D_DESC 구조체에서 설정 가능하며 하나의 리소스에 있는 모든 텍스처의 크기, 데이터 형식, 밉맵 레벨은 같아야 한다.



 매개 변수

 설명 

 pDesc

 D3D11_TEXTURE2D_DESC 구조체에 대한 포인터

 pInitailData

 서브 리소스를 서술하는 D3D11_SUBRESOURCE_DATA 구조체에 대한 배열

 텍스처를 텍셀 데이터로 초기화하기 위해서는 이 구조체로 텍스처 데이터를 지정해야 한다.

 NULL을 지정하면 서브 리소스를 나중에 지정하겠다는 의미이다.

 텍스처가 D3D11_USAGE_IMMUTABLE을 사용하여 생성하였다면 이 값에 NULL을 사용할 수 없다.

 다중 샘플링되는 리소스는 생성 중에 초기화할 수 없기 때문에 이 값은 반드시 NULL이 되어야 한다.

 ppTexture2D

 생성된 텍스처에 대한 인터페이스에 대한 포인터

 이 값을 NULL로 설정하면 입력 매개 변수의 유효성을 검사할 수 있다. 이 경우 S_FALSE가 반환되면 유효하다는 의미이다

 


D3D11_SUBRESOURCE_DATA 구조체

리소스의 서브 리소스를 초기화하는 구조체

 

 멤버 변수

 설명 

 pSysMem

 초기화 데이터에 대한 포인터

 SysMemPitch

 텍스처의 특정 줄의 시작에서 다음 줄의 시작까지의 바이트 수

 이 값은 2차원, 3차원 텍스처 데이터를 초기화할 때 사용하고 다른 리소스에서는 의미가 없다.

 SysMemSlicePitch

 특정 깊이 레벨의 시작에서 다음 깊이 레벨까지의 바이트 수

 이 값은 3차원 텍스처를 초기화할 때 사용하고 다른 리소스에서는 의미가 없다.

 


D3DX11CreateTextureFromFile() 함수

파일로부터 텍스처 리소스를 생성하기 위한 함수

 

 매개 변수

 설명 

 pDevice

 디바이스 인터페이스에 대한 포인터

 pSrcFile

 파일의 이름

 pLoadInfo

 파일에서 텍스처 데이터를 어떻게 읽을 것인가를 지정하는 D3DX11_IMAGE_LOAD_INFO 구조체

 이 구조체를 설정하면 내용에 맞게 텍스처를 로드하며 NULL을 설정하면 텍스처 파일에서 텍스처 데이터의 특성을 읽어서 로드한다.

 pPump

 스레드 펌프 인터페이스 ( ID3DX11ThreadPump)에 대한 포인터

 스레드 펌프는 어떤 작업을 비동기적으로 수행하기 위해 사용된다.

 스레드 펌프를 설정하면 텍스처 파일을 읽기 위해 이 함수가 별도의 스레드를 통해 비동기적으로 수행된다.

 NULL을 지정하면 동기적으로 실행된다.

 스레드 펌프는 D3DX11CreateThreadPump() 함수로 생성한다.

 ppTexture

 생성된 텍스처 리소스( ID3D11Resource )에 대한 포인터의 수조

 pHResult

 함수 반환값을 저장할 변수의 주소

 스레드 펌프를 사용하지 않으면 NULL을 지정한다. 

 스레드 펌프를 사용하면 이 메모리 주소는 함수 호출이 비동기적으로 완료될 때까지 유효해야 한다

 


D3DX11CreateShaderResourceViewFromFile() 함수

파일로부터 쉐이더 리소스 뷰를 생성하기 위해 사용된다.

 


 

 매개 변수

 설명 

 pDevice

 디바이스 인터페이스에 대한 포인터

 pSrcFile

 파일의 이름

 pLoadInfo 

 파일에서 텍스처 데이터를 어떻게 읽을 것인가를 지정하는 D3DX11_IMAGE_LOAD_INFO 구조체

 이 구조체를 설정하면 내용에 맞게 텍스처를 로드하며 NULL을 설정하면 텍스처 파일에서 텍스처 데이터의 특성을 읽어서 로드한다

 pPump

 스레드 펌프 인터페이스 ( ID3DX11ThreadPump)에 대한 포인터

 스레드 펌프는 어떤 작업을 비동기적으로 수행하기 위해 사용된다.

 스레드 펌프를 설정하면 텍스처 파일을 읽기 위해 이 함수가 별도의 스레드를 통해 비동기적으로 수행된다.

 NULL을 지정하면 동기적으로 실행된다.

 스레드 펌프는 D3DX11CreateThreadPump() 함수로 생성한다.

 ppShaderResourceView

 쉐이더 리소스 뷰 인터페이스 ( ID3D11ShaderResourceView )에 대한 포인터의 주소

 pHResult

 함수 반환값을 저장할 변수의 주소

 스레드 펌프를 사용하지 않으면 NULL을 지정한다. 

 스레드 펌프를 사용하면 이 메모리 주소는 함수 호출이 비동기적으로 완료될 때까지 유효해야 한다

 


D3DX11_IMAGE_LOAD_INFO 구조체

파일에서 텍스처를 로드하는 함수가 텍스처를 어떻게 로드할 것인가를 설정하기 위해 사용되는 구조체

 

 멤버 변수

 설명 

 Width

 생성할 텍스처의 가로 크기

 파일에서 로드할 텍스처의 가로 크기가 이 값보다 크거나 작으면 텍스처의 크기가 이 값에 맞도록 변환된다.

 Height

 생성할 텍스처의 세로 크기

 파일에서 로드할 텍스처의 세로 크기가 이 값보다 크거나 작으면 텍스처의 크기가 이 값에 맞도록 변환된다.

 Depth

 텍스처의 깊이

 볼륨 텍스처에만 적용된다

 FirstMipLevel

 텍스처의 가장 큰 해상도의 밉맵 레벨

 이 값이 0보다 크면 텍스처가 로드된 후에 FirstMipLevel은 밉맵 레벨 0으로 매핑된다.

 MipLevels

 텍스처의 최대 밉맵 레벨 

 0 또는 D3DX11_DEFAULT 을 지정하면 최대 밉맵을 가진 텍스처가 생성된다.

 Usage

 텍스처 리소스에 적용될 D3D11_USAGE 열거형 상수

 BindFlags

 텍스처 리소스에 적용될 D3D11_BIND_FLAG 열거형 상수

 CPUAccessFlags

 이 텍스처에 대한 CPU 접근 권한을 나타내는 D3D11CPU_ACCESS_FLAG 열거형 상수

 D3D11_CPU_ACCESS_WRITE 또는 D3D11_CPU_ACCESS_READ를 사용한다.

 가능하면 CPU가 이 텍스처에 접근할 수 없도록 0을 사용한다.

 MiscFlags

 텍스처 리소스에 대한 추가적인 특성을 설정하는 D3D11_RESOURCE_MISC_FLAG 열거형 상수

 Format

 텍스처의 데이터 형식을 나타내는 DXGI_FORMAT 열거형 상수

 Filter

 텍스처에 적용할 필터를 지정하기 위한 D3DX11_FILTER_FLAG 열거형 상수

 MipFilter

 텍스처 밉맵에 적용할 필터를 지정하기 위한 D3DX11_FILTER_FLAG 열거형 상수

 D3D11_FILTER_NONE, D3DX11_FILTER_POINT, D3DX11_FILTER_LINEAR, D3DX11_FILTER_TRIANGLE 을 사용할 수 있다

 pSrcInfo

 원래 이미지에 대한 정보를 나타내는 D3DX11_IMAGE_INFO 구조체

 D3DX11GetImageInfoFromFIle(), D3DX11GetImageInfoFromMemory(), D3DX11GetImageInfoFromResource() 함수 중 하나를 사용하여 D3DX11_IMAGE_INFO 구조체의 정보를 얻는다.

 

D3DX11_IMAGE_LOAD_INFO 구조체는 사용하지 않을 멤버 변수는 설정하지 않는다. 또한 ZeroMemory 함수를 사용하지 않는다.


ID3D11DeviceContext::UpdateSubresource() 함수

CPU가 시스템 메모리의 내용을 맵핑할 수 없는 메모리에 생성된 리소스로 복사한다.


 

 매개 변수

 설명 

 pDstResource

 복사할 목표 리소스에 대한 포인터

 리소스가 D3D11_USAGE_IMMUTABLE, 깊이/스텐실 버퍼, 다중 샘플링으로 생성되었다면 목표 리소스를 사용할 수 없다.

 DstSburesource

 목표 서브 리소스를 나타내는 인덱스

 인덱스는 D3D11CalcSubresource() 함수를 사용하여 계산한다.

 pDstBox

 목표 서브 리소스의 일부분을 나타내는 박스에 대한 포인터

 좌표 단위는 버퍼에는 바이트를 사용하고 텍스처에는 텍셀을 사용한다.

 이 값이 NULL이면 데이터를 목표 서브 리소스에 그대로 복사한다.

 소스의 크기는 목표의 크기와 같아야 한다.

 쉐이더 상수 버퍼의 일부분만 바꾸는 것은 허용되지 않아 쉐이더 상수 버퍼에는 이 값을 NULL로 설정한다

 pSrcData

 복사할 데이터를 나타내는 시스템 메모리의 포인터

 SrcRowPitch

 복사할 데이터의 한 줄의 바이트 크기

 SrcDepthPitch

 복사할 데이터의 깊이 슬라이스 하나의 크기

 


D3D11CalcSubresource() 멤버 함수

텍스처의 서브 리소스 인덱스를 계산하기 위해 사용된다.

버퍼는 구조화되지 않은 리소스이므로 서브 리소스가 하나이다. 따라서 버퍼에 대해서는 이 함수를 사용하지 않는다.

텍스처는 구조화된 리소스이다. 텍스처는 텍스처 배열의 크기와 밉맵 레벨의 개수를 따라 하나 이상의 서브 리소스를 가진다.

 

 매개 변수

 설명 

 MipSlice

 밉맵 레벨의 배열의 인덱스

 0은 첫 번째 밉맵 레벨을 나타낸다.

 ArraySlice

 텍스처의 배열에서 사용할 첫 번째 텍스처의 인덱스 

 MipLevels 

 사용할 밉맵 레벨의 개수

 


리소스의 제약

리소스는 제약이 존재한다.

 리소스

 제약 

 상수 버퍼의 원소 개수

 4096개 

 하나의 버퍼에서 텍셀의 개수

 227텍셀 

 Texture1D U 차원

 8192 

 Texture1DArray 차원

 512 배열 슬라이스 

 Texture2D U/V 차원

 8192 

 Texture2DArray 차원

 512 배열 슬라이스 

 Texture3D U/V/W 차원

 2048 

 TextureCube 차원

 8192 

 리소스 크기

 128MB 

 이방성(Anisotropic) 필터링(Maxanisotropy)

 16

 하드웨어에서 주소로 참조할 수 있는 리소스 차원

 차원마다 8192 

 IA 또는 VS/GS/PS 리소스 크기

 128MB 

 컨텍스트 하나의 리소스 뷰의 최대 개수

 220 

 버퍼 구조체의 크기

 2048 바이트 

 스트림 출력의 크기 

 227 텍셀 

 Draw() / DrawInstanced() 정점 카운트 (인스턴싱 포함 )

 232 

 DrawIndextd[Instanced])( ) 정점 카운트 ( 인스턴싱 포함 )

 232 

 GS 호출 출력 데이터( 요소의 개수 * 정점의 개수 )

 1024 

 컨텍스트 하나의 샘플러 객체의 전체 개수

 4096 

 파이프라인의 뷰 포트/시저 객체의 전체 개수

 16 

 정점마다 Clip/Cull 거리의 전체 개수

 8 

 컨텍스트마다 블렌드 객체의 전체 개수

 4096 

 컨텍스트마다 깊이/스텐실 객체의 전체 개수

 4096 

 컨텍스트마다 래스터라이저 상태 객체의 전체 개수

 4096 

 다중 샘플링 동안 픽셀당 최대 샘플 수

 32 

 쉐이더 리소스 정점의 원소 수 ( 4개의 32비트 요소 )

 16 

 정점 쉐이더에서 입력 레지스터 개수(4개의 32비트 요소)

 16 

 정점 쉐이더에서 출력 레지스터 개수(4개의 32비트 요소)

 16 

 기하 쉐이더에서 입력 레지스터 개수(4개의 32비트 요소)

 16 

 기하 쉐이더에서 출력 레지스터 개수(4개의 32비트 요소)

 32 

 픽셀 쉐이더에서 입력 레지스터 개수(4개의 32비트 요소)

 32 

 픽셀 쉐이더에서 출력 레지스터 개수(4개의 32비트 요소)

 8 

 픽셀 쉐이더에서 출력 깊이 레지스터 개수(1개의 32비트 요소)

 1 

 입력 조립기에서 인덱스 입력 리소스 슬롯의 개수

 1 

 입력 조립기에서 정점 입력 리소스 슬롯의 개수

 16 



출처 : http://blog.naver.com/ram1029123/220419267617

728x90
728x90

NVIDIA 그래픽 카드에서만 CUDA가 동작을 한다.


DirectX11을 초기화하는 단계에서 그래픽 카드 정보를 확인하고, NVIDIA 그래픽 카드가 아닌 경우 경고를 띄우기 위해서 


DXGI_ADAPTER_DESC 구조체를 사용하여 확인하였다.



<소스 코드>


CComPtr<IDXGIFactory1> factory = nullptr;

HR(CreateDXGIFactory1(__uuidof(IDXGIFactory1), (void**)&factory));


if (FAILED(factory->EnumAdapters1(m_nAdapterID, &m_pAdapter)))

    return E_FAIL;    // 그래픽 카드가 없기 때문에 종료


DXGI_ADAPTER_DESC desc;

m_pAdapter->GetDesc(&desc);




위와 같이 그래픽 카드의 정보를 가져와서 확인하면 된다.



728x90
728x90

DirectX11을 이용한 Application을 개발하는 도중에 이상한 현상을 발견하였다.


이 현상은 NVidia 계열의 그래픽 카드에서는 발생하지 않고, AMD 계열의 그래픽 카드에서만 발생하였다.


이 현상은 Application 내에서 Device 및 Context 등의 자원들을 계속 생성 및 해제 하다가 DirectX 함수에서 빠져나오지 


못하고 계속 멈춰있는 현상이다.


며칠 테스트를 해본 결과...


CreateBlendState() 함수를 사용할 때 ID3D11BlendState 변수를 생성하고, 해제를 하지 않거나,


CreateSamplerState() 함수를 사용할 때 ID3D11SamplerState 변수를 생성하고, 해제를 하지 않거나,


CreateRasterizerState() 함수를 사용할 때 ID3D11RasterizerState 변수를 생성하고, 해제를 하지 않거나,


등등의 다양한 경우가 있을 것이다.


뭐든 이러한 변수들을 해제하지 않으면서, ID3D11Device등의 리소스를 생성 및 해제를 반복하게 되면, DirectX 함수에서 빠져나오지 못한다.



ps. 생성한 것은 반드시 해제하도록 하자...

728x90
728x90

DirectX SDK 를 설치하지 않고 Windows를 설치할 때 같이 설치된 라이브러리들로 작업을 하려면 기존의 내용을 조금씩 변경을 해야한다.


나의 경우 DXTrace()를 잘 쓰고 있었는데, 이것은 따로 넣어주어야 한다.

DxErr.zip


Shader를 읽기 위해서 사용하는 D3DX11CompileFromFile() -> D3DCompileFromFile() 로 변경되었다.

이 함수를 사용하기 위해서는 헤더와 라이브러리를 추가해야한다.

#include <d3dcompiler.h>

#pragma comment(lib, "d3dcompiler.lib")


구조체 D3DXVECTOR -> DirectX::XMFLOAT 으로 변경되었다. (뒤에 숫자는... 생략)

이 구조체를 사용하기 위해서는 헤더만 추가하면 된다.

#include <DirectXMath.h>

#include <DirectXPackedVector.h>

using namespace DirectX; <- 를 사용해도 무관하지만.... 이전의 회사 프로젝트에서 namespace가 꼬여서 고생한적이 있기 때문에 나는 그냥 namespace를 앞에 붙여서 사용한다. 


함수 D3DX11CreateShaderResourceViewFromMemory() -> CreateWICTextureFromMemory() 로 변경되었다.

dds, tga를 제외한 이미지 파일을 불러올 땐 위의 함수를 사용하면 된다.

#include "WICTextureLoader.h" 를 추가할 것.


이것의 경우 기본적으로 라이브러리가 없기 때문에 https://directxtex.codeplex.com/ 에서 받아서 빌드후 사용하면 되지만, 나는 이미 빌드해서 썻으니까 따로 올린다.

DirectXTex-master.zip




728x90
728x90

D3DX11_IMAGE_LOAD_INFO LoadInfo;


HR(D3DX11CreateShaderResourceViewFromMemory(in_pDevice, BmpImage, BmpImageSize &LoadInfo, nullptr, &m_pSRV, nullptr));



bmp 파일의 크기를 약 30 ~ 40 MB를 D3DX11CreateShaderResourceViewFromMemory()에서 불러오니  


E_INVALIDARG 에러가 발생했다.


E_INVALIDARG 에러는 쉽게 말하면 잘못된 매개변수를 이용하여 함수를 호출했다는 뜻이다.


그래서 모든 매개변수의 값을 확인햇는데 문제가 없었다.


마지막으로 혹시나하고 LoadInfo의 값을 Default 값이 아닌 임의의 크기로 지정을 하니 해결되었다..


D3DX11_IMAGE_LOAD_INFO LoadInfo;

LoadInfo.Width = nTempWidth;

LoadInfo.Height = nTempHeight;

LoadInfo.Usage = D3D11_USAGE_DEFAULT;

LoadInfo.BindFlags = D3D11_BIND_SHADER_RESOURCE;

LoadInfo.CpuAccessFlags = 0;


HR(D3DX11CreateShaderResourceViewFromMemory(in_pDevice, BmpImage, BmpImageSize &LoadInfo, nullptr, &m_pSRV, nullptr));


이 bmp 파일의 Width는 38611, Height는 1080으로 FULL HD를 기준으로 약 모니터 20개의 크기의 텍스처를 불러오려니 

죽은 것일 것이다...

728x90
728x90

Device Lost는 DirectX를 개발하면 반드시 거쳐야하는 관문 중 하나이다. (OpenGL도 Device Lost가 있겠지... ?)


Device Lost란 쉽게 말하면 시스템의 리소스를 모두 잃어버려서 사용할 수 없게 되어버린 상태이다.


Device Lost가 발생하게 되는 이유는 Alt+Tab, 실시간 화면 크기 변경, 그래픽 카드가 죽어버리는 현상등 다양한 이유가 있다.


DirectX 11 에서는 디바이스 로스트가 거의 일어나지 않지만, 몇가지 예외적 상황에서는 디바이스 로스트가 일어난다.

 

예를들어 GPU가 Hang Up 상태가 되어 장시간 응답이 없을 경우 OS의 타임 아웃처리가 발동하여 GPU가 리셋 된다.

 

이경우에도 OS의 재부팅은 필요없지만 어플리케이션측에서 만든 DirectX 11 디바이스 나 오브젝트등은 모두 파기하고

새로이 만들어야 한다.

 

디바이스 로스트가 일어났는지는 ID3D11Device::GetDeivceRemovedReason() 함수를 호출하여 조사 할 수 있다.

 

반환값이 S_OK가 아닌 경우 몇가지 이유로인해 디바이스 로스트가 발생한다

 

 

  • DXGI_ERROR_DEVICE_HUNG : 어플리케이션에서 보낸 잘못된 형식의 명령으로 인해 디바이스가 실패했다.
  • DXGI_ERROR_DEVICE_RESET : 잘못된 형식의 명령으로 인해 디바이스가 실패했다.                                                                           디바이스가 커맨드 실행에 타당하지 않은 시간을 필요로하고있는  하드웨어 크래시/행 상태이다
  • DXGI_ERROR_DEVICE_REMOVED : 그래픽스 아답터(비디오 카드)의 플러그&플레이가 정지되었다.                                                               아답터가 이용불능 상태일 가능성이 높음

 

 

  • DXGI_ERROR_DRIVER_INTERVAL_ERROR : 드라이버가 정의되지 않은 오퍼레이션을 수행했다
  • DXGI_ERROR_INVALID_CALL  : 어플리케이션이 유효하지 않은 파라미터를 제공했다.

 

 

 

DXGI_ERROR_DEVICE_HUNG  DXGI_ERROR_DEVICE_RESET 일 경우에는 DirectX 11 디바이스나 

오브젝트를 재생성함으로 복구할수 도 있다

 

DXGI_ERROR_DEVICE_REMOVED , DXGI_ERROR_INVALID_CALL  는 어플리케이션측에서 어쩔수없는 부분이다

 


BOOL  CheckDeviceLost()

{
    HRESULT hr;

    hr = g_pd3dDevice->GetDeviceRemovedReason();     //디바이스 로스트가 일어났는지 조사

    switch(hr)
    {
        case S_OK :                                                        //정상
        break;

        case DXGI_ERROR_DEVICE_HUNG:
        case DXGI_ERROR_DEVICE_RESET:
            CleanupDevice();                                             // device Release
            InitDevice();                                                    //  device Init

            if(FAILED(hr))
                return FALSE;                                             //실패. 어플리케이션 종료
        break;

        case DXGI_ERROR_DEVICE_REMOVED:
        case DXGI_ERROR_DRIVER_INTERNAL_ERROR:
        case DXGI_ERROR_INVALID_CALL:
        default:
            return FALSE;                                               //실패. 어플리케이션 종료
    }
    return TRUE;
}

 

 

더 자세한 부분은 MSDN을 참조하길..

http://msdn.microsoft.com/en-us/library/windows/desktop/bb509553(v=vs.85).aspx



출처 : http://blog.naver.com/PostView.nhn?blogId=rhkd2060&logNo=140203208989&parentCategoryNo=&categoryNo=20&viewDate=&isShowPopularPosts=true&from=search

728x90
728x90

모두가 알고있듯이 OMSetRenderTargets()의 사용법은 아래와 같다.


m_pImmediateContext->OMSetRenderTargets(1, &pRenderTarget_1, nullptr);


Rendering();


m_pImmediateContext->OMSetRenderTargets(1, &pRenderTarget_2, nullptr);


Rendering();



이 DeferredContext에서도 동일하게 OMSetRenderTargets() 함수가 있었기 때문에, 아무 생각 없이 아래와 같이 만들었었다.


m_pImmediateContext->OMSetRenderTargets(1, &pRenderTarget_1, nullptr);

for (int i = 0; i < MAX_DEFERRED_COUNT; ++i)

    m_pDeferredContext[i]->OMSetRenderTargets(1, &pRenderTarget_1, nullptr);


Rendering();


m_pImmediateContext->OMSetRenderTargets(1, &pRenderTarget_2, nullptr);

for (int i = 0; i < MAX_DEFERRED_COUNT; ++i)

    m_pDeferredContext[i]->OMSetRenderTargets(1, &pRenderTarget_2, nullptr);


Rendering();



그랬더니, 엄청난 메모리 증가량을 볼 수 있었다. ㅎㅎ....


결국 확인해 보니, DeferredContext에 대해서는 별도의 OMSetRenderTargets()를 설정하지 않아도 문제없이


여러 개의 RenderTarget에 그리는 것을 확인하였다.

728x90

+ Recent posts