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

이번 프로젝트 중에 LOGFONT를 쓸 일이 있어서 LOGFONTA로 작업을 했다가 LOGFONTW로 변경해야 하는 시점이 왔다.


그래서 SetTitle(, , , , LOGFONTA) -> SetTitle(, , , , LOGFONTW) 로 변경하는 작업을 진행하는 도중 이상한 현상을 발견하였다.



int main()

{

LOGFONTW lf; <- 정상적인 값 세팅.


SetTitle(, , , , lf );

}


void SetTitle(, , , , LOGFONTW in_lf)

{

in_lf; <- 이 시점에서 봤을 때 값은 쓰레기 값이었다.

}



그래서 Packing 크기와 구조체의 크기 등등을 비교해도 다 같은데 왜 값이 서로 다른지에 대해 찾아보던 중


메모리 값을 비교해보니 lf의 주소값이 in_lf의 첫번째 멤버변수에 들어가 있는 것을 확인했다.


그래서 이런저런 테스트를 더 해보려고했지만, 개발 일정이 늦은 상태이기 때문에 다음에 더 테스트를 더 해봐야 할듯하다. ㅎㅎ



결론은


void SetTitle(, , , , LOGFONTW in_lf) -> void SetTitle(, , , , const LOGFONTW& in_lf) 로 바꾸면 정상적인 값으로 들어간다.

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



이 메세지의 경우 개발하면서 되게 자주보게 된다.... (코딩을 못해서 그런가...)


DirectX11로 개발하면서 특정 하드웨어 스펙에서만 이 에러가 발생해서 인터넷을 찾아봤더니,


MS에서 좋은 자료를 찾았다.


https://support.microsoft.com/en-us/kb/2628738


https://msdn.microsoft.com/en-us/library/windows/hardware/ff569918(v=vs.85).aspx



쉽게 말해서, 레지스트리를 수정하여 디스플레이의 작업 시간이 2초가 넘어가도, 디스플레이의 재시작을 하지 않는 방법이다. (8초로 수정)



cmd -> regedit -> HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\GraphicsDrivers -> TdrDelay(8)

-

728x90
728x90


DLL 파일이 불러지지 않을 때, 연결되지 않은 파일이 있는지 등등을 확인할 때 사용하는 유용한 프로그램.




depends22_x64.zip

depends22_x86.zip

728x90

'Dev Tool' 카테고리의 다른 글

Dev Tool - GPS Korea 좌표 변환기  (0) 2017.04.20
Dev Tool - TortoiseSVN  (0) 2017.02.23
Dev Tool - Doxygen  (0) 2016.04.04
Dev Tool - StarUML  (0) 2016.02.24
Dev Tool - Beyond Compare  (0) 2016.02.24
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
728x90

보통 해상도 구하는건 이걸 사용하죠.


 int iWidth = GetSystemMetrics(SM_CXSCREEN);
 int iHeight = GetSystemMetrics(SM_CYSCREEN);


그런데, 이건 주 모니터의 해상도 밖에 못 구합니다.


아래 걸 사용하면 다중 모니터를 고려한 최대 해상도를 구해 옵니다.


 int iWidth = GetSystemMetrics(SM_CXVIRTUALSCREEN);
 int iHeight = GetSystemMetrics(SM_CYVIRTUALSCREEN);


각 모니터 위치나 세세한 정보도 얻어 올 수 있습니다.


출처 : http://heagi2.blog.me/100093550249

728x90
728x90

프로그래밍을 최적화 하는데에는 크게 2개의 방법이 있다.


1. Memory Access를 줄여라. (Cache를 이용하여 해결 가능)

2. 분기(if)를 줄여라. (예측 분기를 이용하여 해결 가능)



Cache를 하는 기준은 다음과 같다.

1. 시간성. (가져온지 얼마 안된 데이터)

2. 공간성. (가져온 데이터의 근처에 있는 데이터)


for(x = 0; ; )

{

for(y = 0; ;)

{

// 다음과 같은 2중 for문일 때에는 공간성을 위해 가로로 돌게하는 것이 성능에 도움이 된다.

}

}


for()

{

// L1 레지스트리가 32k이고, 하이퍼 스레드의 경우 16k씩 2개가 돌게 된다.

// if 없이  16k이하의 크기만 돌게 작성해야 한다. Cache보다 데이터가 크다면 Cache가 아예 동작을 하지 않는다.

// if가 7개 이상 있으면 예측 분기가 불가능 하다.

}


출처 : 회사 세미나 중에서...


728x90

+ Recent posts