diff --git a/README.md b/README.md index 82c450b..e6cf5fb 100644 --- a/README.md +++ b/README.md @@ -60,3 +60,6 @@ Solo developers can contribute to the project in various ways including implemen All submissions by solo developers should be done via a pull request submission that includes a description of the change and for code changes the set of tests that were run. If a part or all of a submission is rejected, a clear explaination will be provided to the contributor along with guidance on what issues if any can be addressed in order for the submission to be accepted. + +The [ISO C++ Core guidelines](https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md) are a good read for anyone hoping to contribute to the project, as we are attempting to follow the bulk of the recommendations especially with respect to resource management. This project uses exceptions and therefore also uses RIAA. + diff --git a/render-only-sample/CubeTest/CubeTest_new.cpp b/render-only-sample/CubeTest/CubeTest_new.cpp index 4de6b69..714b348 100644 --- a/render-only-sample/CubeTest/CubeTest_new.cpp +++ b/render-only-sample/CubeTest/CubeTest_new.cpp @@ -424,11 +424,147 @@ class D3DDefaultTexture std::shared_ptr m_pDevice; }; +const char *DXGIFormatToString(DXGI_FORMAT format) +{ + switch (format) + { + case DXGI_FORMAT_R8G8B8A8_UNORM: + return "R8G8B8A8_UNORM"; + + case DXGI_FORMAT_R8G8_UNORM: + return "DXGI_FORMAT_R8G8_UNORM"; + + case DXGI_FORMAT_R8_UNORM: + return "DXGI_FORMAT_R8_UNORM"; + + case DXGI_FORMAT_A8_UNORM: + return "DXGI_FORMAT_A8_UNORM"; + + default: + return "UNKNOWN"; + } +} + class D3DBitmapTexture { public: - D3DBitmapTexture(std::shared_ptr & inDevice) + UINT GetFormatBytesPerPixel(DXGI_FORMAT inFormat) + { + switch (inFormat) + { + case DXGI_FORMAT_R8G8B8A8_UNORM: + { + return 4; + } + break; + + case DXGI_FORMAT_R8G8_UNORM: + { + return 2; + } + break; + + case DXGI_FORMAT_R8_UNORM: + { + return 1; + } + break; + + case DXGI_FORMAT_A8_UNORM: + { + return 1; + } + break; + + default: + { + throw std::exception("Not implemented texture color format passed"); + } + + } + } + + std::unique_ptr ConvertTextureFromRGBA(PBYTE _In_ pTexels, DXGI_FORMAT _In_ outFormat, ULONG _In_ texWidth, ULONG _In_ texHeight, UINT _Out_ &outTextureBytesPerPixel) + { + outTextureBytesPerPixel = GetFormatBytesPerPixel(outFormat); + std::unique_ptr colorConvertedBuffer(new BYTE[texWidth * texHeight * outTextureBytesPerPixel]); + BYTE *colorConvertedBufferRaw = (BYTE*)colorConvertedBuffer.get(); + + switch (outFormat) + { + case DXGI_FORMAT_R8G8B8A8_UNORM: + { + // Just do the copy + UINT pSysPitch = texWidth * outTextureBytesPerPixel; + for (UINT k = 0; k < texHeight; k++) + { + memcpy(colorConvertedBufferRaw, pTexels, pSysPitch); + colorConvertedBufferRaw += pSysPitch; + pTexels += pSysPitch; + } + + return colorConvertedBuffer; + } + + case DXGI_FORMAT_R8G8_UNORM: + { + // Extract only red and green colors + for (UINT k = 0; k < texHeight; k++) + { + for (UINT i = 0; i < texWidth * 4; i += 4) + { + BYTE red = pTexels[i]; + BYTE green = pTexels[i + 1]; + + *colorConvertedBufferRaw++ = (BYTE)red; + *colorConvertedBufferRaw++ = (BYTE)green; + } + pTexels += texWidth * 4; + } + return colorConvertedBuffer; + } + + case DXGI_FORMAT_R8_UNORM: + { + // Extract only red color + for (UINT k = 0; k < texHeight; k++) + { + for (UINT i = 0; i < texWidth * 4; i += 4) + { + BYTE red = pTexels[i]; + *colorConvertedBufferRaw++ = (BYTE)red; + } + pTexels += texWidth * 4; + } + return colorConvertedBuffer; + } + + case DXGI_FORMAT_A8_UNORM: + { + // Fill with some red-based alpha + for (UINT k = 0; k < texHeight; k++) + { + for (UINT i = 0; i < texWidth * 4; i += 4) + { + BYTE red = pTexels[i]; + *colorConvertedBufferRaw++ = (BYTE)red; + } + pTexels += texWidth * 4; + } + + return colorConvertedBuffer; + } + + default: + { + throw std::exception("Not implemented texture color format passed"); + } + } + + } + + D3DBitmapTexture(std::shared_ptr & inDevice, DXGI_FORMAT textureFormat = DXGI_FORMAT_R8G8B8A8_UNORM) { ULONG texWidth, texHeight, resSize; PVOID pRes; @@ -452,7 +588,7 @@ class D3DBitmapTexture desc.Height = texHeight; desc.MipLevels = 1; desc.ArraySize = 1; - desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + desc.Format = textureFormat; desc.SampleDesc.Count = 1; desc.SampleDesc.Quality = 0; desc.Usage = D3D11_USAGE_DEFAULT; @@ -462,10 +598,12 @@ class D3DBitmapTexture D3D11_SUBRESOURCE_DATA initData; ZeroMemory(&initData, sizeof(initData)); - initData.pSysMem = pTexels; - initData.SysMemPitch = texWidth * 4; - initData.SysMemSlicePitch = texWidth * 4 * texHeight; + UINT bytesPerPixel = 0; + auto texture = ConvertTextureFromRGBA(pTexels, textureFormat, texWidth, texHeight, bytesPerPixel); + initData.SysMemPitch = texWidth * bytesPerPixel; + initData.SysMemSlicePitch = texWidth * texHeight * bytesPerPixel; + initData.pSysMem = texture.get(); ID3D11Texture2D * pTexture; hr = inDevice->GetDevice()->CreateTexture2D(&desc, &initData, &pTexture); @@ -1204,8 +1342,10 @@ class D3DEngine { public: - D3DEngine() + D3DEngine(DXGI_FORMAT textureFormat = DXGI_FORMAT_R8G8B8A8_UNORM) { + + m_textureFormat = textureFormat; #if USE_VC4 m_pDevice = std::shared_ptr(new D3DDevice(L"Render Only Sample Driver")); #else @@ -1250,7 +1390,7 @@ class D3DEngine m_pPSConstantBuffer = std::unique_ptr(new D3DPSConstantBuffer(m_pDevice)); #if USE_BITMAP_TEX - m_pDefaultTexture = std::unique_ptr(new D3DBitmapTexture(m_pDevice)); + m_pDefaultTexture = std::unique_ptr(new D3DBitmapTexture(m_pDevice, m_textureFormat)); #else m_pDefaultTexture = std::unique_ptr(new D3DDefaultTexture(m_pDevice, 256, 256)); #endif // USE_BITMAP_TEX @@ -1361,7 +1501,7 @@ class D3DEngine { char fileName[MAX_PATH]; #if USE_VC4 - sprintf_s(fileName, MAX_PATH, "c:\\temp\\image_%d_vc4.bmp", iFrame); + sprintf_s(fileName, MAX_PATH, "c:\\temp\\image_%s_%d_vc4.bmp", DXGIFormatToString(m_textureFormat),iFrame); #else sprintf_s(fileName, MAX_PATH, "c:\\temp\\image_%d_warp.bmp", iFrame); #endif // USE_VC4 @@ -1395,6 +1535,7 @@ class D3DEngine std::unique_ptr m_pSamplerState; std::unique_ptr m_pVSConstantBuffer; std::unique_ptr m_pPSConstantBuffer; + DXGI_FORMAT m_textureFormat; #if USE_BITMAP_TEX std::unique_ptr m_pDefaultTexture; #else @@ -1434,132 +1575,147 @@ BOOL InitPerf() return hQueueEvent ? true : false; } +const UINT TESTED_FORMATS_COUNT = 4; + int main(int argc, char* argv[]) { - try + + DXGI_FORMAT formatsToTest[TESTED_FORMATS_COUNT] = { - BOOL bPerfMode = false; + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8_UNORM, + DXGI_FORMAT_R8_UNORM, + DXGI_FORMAT_A8_UNORM + }; - LARGE_INTEGER framesStart; - LARGE_INTEGER framesEnd; + BOOL bPerfMode = false; - LARGE_INTEGER frequenceStart; - LARGE_INTEGER frequenceEnd; + LARGE_INTEGER framesStart; + LARGE_INTEGER framesEnd; - if (argc >= 3) - { - bPerfMode = true; - } + LARGE_INTEGER frequenceStart; + LARGE_INTEGER frequenceEnd; - if (bPerfMode) - { - sscanf_s(argv[1], "%d", &kWidth); - sscanf_s(argv[2], "%d", &kHeight); + if (argc >= 3) + { + bPerfMode = true; + } - if (argc > 3) - { - sscanf_s(argv[3], "%d", &frames); + if (bPerfMode) + { + sscanf_s(argv[1], "%d", &kWidth); + sscanf_s(argv[2], "%d", &kHeight); - if (frames < 20) - { - frames = 20; - } - } - else + if (argc > 3) + { + sscanf_s(argv[3], "%d", &frames); + + if (frames < 20) { frames = 20; } } - - D3DEngine engine; - - if (bPerfMode) + else { - pd3dDevice = engine.GetDevice(); - pd3dContext = engine.GetContext(); - - InitPerf(); + frames = 20; } + } - float t = 0.0f; - for (UINT i = 0; i < frames; i++) + for (int currentTest = 0; currentTest < TESTED_FORMATS_COUNT; currentTest++) + { + printf("Test for [%s] \n", DXGIFormatToString(formatsToTest[currentTest])); + try { - // Skip the 1st frame for shader compilation time - if (bPerfMode && (i == 1)) + D3DEngine engine(formatsToTest[currentTest]); + + if (bPerfMode) { - QueryPerformanceCounter(&framesStart); - QueryPerformanceFrequency(&frequenceStart); - } + pd3dDevice = engine.GetDevice(); + pd3dContext = engine.GetContext(); - t += (float)XM_PI * 0.125f; - engine.Render(i, t, bPerfMode); + InitPerf(); + } - if (bPerfMode) + float t = 0.0f; + for (UINT i = 0; i < frames; i++) { - if (i == 0) + // Skip the 1st frame for shader compilation time + if (bPerfMode && (i == 1)) { - // - // Wait for the 1st frame to finish to account for the GPU paging cost - // + QueryPerformanceCounter(&framesStart); + QueryPerformanceFrequency(&frequenceStart); + } - DWORD dwWaitResult; + t += (float)XM_PI * 0.125f; + engine.Render(i, t, bPerfMode); - pDxgiDev2->EnqueueSetEvent(hQueueEvent); + if (bPerfMode) + { + if (i == 0) + { + // + // Wait for the 1st frame to finish to account for the GPU paging cost + // - dwWaitResult = WaitForSingleObject( - hQueueEvent, // event handle - INFINITE); // indefinite wait + DWORD dwWaitResult; - ResetEvent(hQueueEvent); - } - else if (i < (frames - 1)) - { - pd3dContext->Flush(); - } - else - { - pDxgiDev2->EnqueueSetEvent(hQueueEvent); - } - } - } + pDxgiDev2->EnqueueSetEvent(hQueueEvent); - if (bPerfMode) - { - DWORD dwWaitResult; + dwWaitResult = WaitForSingleObject( + hQueueEvent, // event handle + INFINITE); // indefinite wait - dwWaitResult = WaitForSingleObject( - hQueueEvent, // event handle - INFINITE); // indefinite wait + ResetEvent(hQueueEvent); + } + else if (i < (frames - 1)) + { + pd3dContext->Flush(); + } + else + { + pDxgiDev2->EnqueueSetEvent(hQueueEvent); + } + } + } - if (dwWaitResult == WAIT_OBJECT_0) + if (bPerfMode) { - QueryPerformanceCounter(&framesEnd); - QueryPerformanceFrequency(&frequenceEnd); + DWORD dwWaitResult; - UINT measuredFrames = frames - 1; + dwWaitResult = WaitForSingleObject( + hQueueEvent, // event handle + INFINITE); // indefinite wait - if (frequenceStart.QuadPart != frequenceEnd.QuadPart) + if (dwWaitResult == WAIT_OBJECT_0) { - printf("Perf frequence changed during %d frames of rendering", measuredFrames); + QueryPerformanceCounter(&framesEnd); + QueryPerformanceFrequency(&frequenceEnd); + + UINT measuredFrames = frames - 1; + + if (frequenceStart.QuadPart != frequenceEnd.QuadPart) + { + printf("Perf frequence changed during %d frames of rendering", measuredFrames); + } + + printf( + "Average rendering time for (%d x %d) from %d frames: %I64d ms\n", + kWidth, + kHeight, + measuredFrames, + ((framesEnd.QuadPart - framesStart.QuadPart) * 1000) / (measuredFrames*frequenceEnd.QuadPart)); } - printf( - "Average rendering time for (%d x %d) from %d frames: %I64d ms\n", - kWidth, - kHeight, - measuredFrames, - ((framesEnd.QuadPart - framesStart.QuadPart) * 1000) / (measuredFrames*frequenceEnd.QuadPart)); + UninitPerf(); } - UninitPerf(); + printf("Success\n"); } - printf("Success\n"); - } - - catch (std::exception & e) - { - printf("ERROR: %s\n", e.what()); + catch (const std::exception &e) + { + printf("ERROR: %s\n", e.what()); + } } printf("Done\n"); diff --git a/render-only-sample/Ros.sln b/render-only-sample/Ros.sln index 2810dcb..e984878 100644 --- a/render-only-sample/Ros.sln +++ b/render-only-sample/Ros.sln @@ -20,15 +20,12 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "roscompiler", "roscompiler\roscompiler.vcxproj", "{98E16C06-7E74-4A0C-A5E6-24219CAE527D}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Vc4Asm", "Vc4Asm\Vc4Asm.vcxproj", "{53098D78-1666-4AE9-AAEA-15EC43D787B0}" - ProjectSection(ProjectDependencies) = postProject - {98E16C06-7E74-4A0C-A5E6-24219CAE527D} = {98E16C06-7E74-4A0C-A5E6-24219CAE527D} - EndProjectSection -EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CubeTest", "CubeTest\CubeTest.vcxproj", "{E462FE3C-960B-4A75-A57D-9C4705ECC8D9}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RosDriver", "rosdriver\RosDriver.vcxproj", "{593E30CD-93AD-432A-B6A1-B59F85C77ACC}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RosTest", "rostest\RosTest.vcxproj", "{5E7D4E14-5AF2-48AB-A551-33C8865A3C47}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -109,18 +106,6 @@ Global {98E16C06-7E74-4A0C-A5E6-24219CAE527D}.Release|x86.ActiveCfg = Release|Win32 {98E16C06-7E74-4A0C-A5E6-24219CAE527D}.Release|x86.Build.0 = Release|Win32 {98E16C06-7E74-4A0C-A5E6-24219CAE527D}.Release|x86.Deploy.0 = Release|Win32 - {53098D78-1666-4AE9-AAEA-15EC43D787B0}.Debug|Any CPU.ActiveCfg = Debug|Win32 - {53098D78-1666-4AE9-AAEA-15EC43D787B0}.Debug|ARM.ActiveCfg = Debug|x64 - {53098D78-1666-4AE9-AAEA-15EC43D787B0}.Debug|ARM64.ActiveCfg = Debug|Win32 - {53098D78-1666-4AE9-AAEA-15EC43D787B0}.Debug|x64.ActiveCfg = Debug|x64 - {53098D78-1666-4AE9-AAEA-15EC43D787B0}.Debug|x64.Build.0 = Debug|x64 - {53098D78-1666-4AE9-AAEA-15EC43D787B0}.Debug|x86.ActiveCfg = Debug|Win32 - {53098D78-1666-4AE9-AAEA-15EC43D787B0}.Release|Any CPU.ActiveCfg = Release|Win32 - {53098D78-1666-4AE9-AAEA-15EC43D787B0}.Release|ARM.ActiveCfg = Release|Win32 - {53098D78-1666-4AE9-AAEA-15EC43D787B0}.Release|ARM64.ActiveCfg = Release|Win32 - {53098D78-1666-4AE9-AAEA-15EC43D787B0}.Release|x64.ActiveCfg = Release|x64 - {53098D78-1666-4AE9-AAEA-15EC43D787B0}.Release|x64.Build.0 = Release|x64 - {53098D78-1666-4AE9-AAEA-15EC43D787B0}.Release|x86.ActiveCfg = Release|Win32 {E462FE3C-960B-4A75-A57D-9C4705ECC8D9}.Debug|Any CPU.ActiveCfg = Debug|Win32 {E462FE3C-960B-4A75-A57D-9C4705ECC8D9}.Debug|ARM.ActiveCfg = Debug|arm {E462FE3C-960B-4A75-A57D-9C4705ECC8D9}.Debug|ARM.Build.0 = Debug|arm @@ -163,6 +148,22 @@ Global {593E30CD-93AD-432A-B6A1-B59F85C77ACC}.Release|x86.ActiveCfg = Release|Win32 {593E30CD-93AD-432A-B6A1-B59F85C77ACC}.Release|x86.Build.0 = Release|Win32 {593E30CD-93AD-432A-B6A1-B59F85C77ACC}.Release|x86.Deploy.0 = Release|Win32 + {5E7D4E14-5AF2-48AB-A551-33C8865A3C47}.Debug|Any CPU.ActiveCfg = Debug|Win32 + {5E7D4E14-5AF2-48AB-A551-33C8865A3C47}.Debug|ARM.ActiveCfg = Debug|ARM + {5E7D4E14-5AF2-48AB-A551-33C8865A3C47}.Debug|ARM.Build.0 = Debug|ARM + {5E7D4E14-5AF2-48AB-A551-33C8865A3C47}.Debug|ARM64.ActiveCfg = Debug|Win32 + {5E7D4E14-5AF2-48AB-A551-33C8865A3C47}.Debug|x64.ActiveCfg = Debug|x64 + {5E7D4E14-5AF2-48AB-A551-33C8865A3C47}.Debug|x64.Build.0 = Debug|x64 + {5E7D4E14-5AF2-48AB-A551-33C8865A3C47}.Debug|x86.ActiveCfg = Debug|Win32 + {5E7D4E14-5AF2-48AB-A551-33C8865A3C47}.Debug|x86.Build.0 = Debug|Win32 + {5E7D4E14-5AF2-48AB-A551-33C8865A3C47}.Release|Any CPU.ActiveCfg = Release|Win32 + {5E7D4E14-5AF2-48AB-A551-33C8865A3C47}.Release|ARM.ActiveCfg = Release|ARM + {5E7D4E14-5AF2-48AB-A551-33C8865A3C47}.Release|ARM.Build.0 = Release|ARM + {5E7D4E14-5AF2-48AB-A551-33C8865A3C47}.Release|ARM64.ActiveCfg = Release|Win32 + {5E7D4E14-5AF2-48AB-A551-33C8865A3C47}.Release|x64.ActiveCfg = Release|x64 + {5E7D4E14-5AF2-48AB-A551-33C8865A3C47}.Release|x64.Build.0 = Release|x64 + {5E7D4E14-5AF2-48AB-A551-33C8865A3C47}.Release|x86.ActiveCfg = Release|Win32 + {5E7D4E14-5AF2-48AB-A551-33C8865A3C47}.Release|x86.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/render-only-sample/Vc4Asm/ReadMe.txt b/render-only-sample/Vc4Asm/ReadMe.txt deleted file mode 100644 index da3cfb8..0000000 --- a/render-only-sample/Vc4Asm/ReadMe.txt +++ /dev/null @@ -1,40 +0,0 @@ -======================================================================== - CONSOLE APPLICATION : Vc4Asm Project Overview -======================================================================== - -AppWizard has created this Vc4Asm application for you. - -This file contains a summary of what you will find in each of the files that -make up your Vc4Asm application. - - -Vc4Asm.vcxproj - This is the main project file for VC++ projects generated using an Application Wizard. - It contains information about the version of Visual C++ that generated the file, and - information about the platforms, configurations, and project features selected with the - Application Wizard. - -Vc4Asm.vcxproj.filters - This is the filters file for VC++ projects generated using an Application Wizard. - It contains information about the association between the files in your project - and the filters. This association is used in the IDE to show grouping of files with - similar extensions under a specific node (for e.g. ".cpp" files are associated with the - "Source Files" filter). - -Vc4Asm.cpp - This is the main application source file. - -///////////////////////////////////////////////////////////////////////////// -Other standard files: - -StdAfx.h, StdAfx.cpp - These files are used to build a precompiled header (PCH) file - named Vc4Asm.pch and a precompiled types file named StdAfx.obj. - -///////////////////////////////////////////////////////////////////////////// -Other notes: - -AppWizard uses "TODO:" comments to indicate parts of the source code you -should add to or customize. - -///////////////////////////////////////////////////////////////////////////// diff --git a/render-only-sample/Vc4Asm/Tests/cs_7_vpmread.asm b/render-only-sample/Vc4Asm/Tests/cs_7_vpmread.asm deleted file mode 100644 index 893e574..0000000 --- a/render-only-sample/Vc4Asm/Tests/cs_7_vpmread.asm +++ /dev/null @@ -1,23 +0,0 @@ -ldi ; mov vr_setup, 0x00701a00 ; nop -ldi ; mov vw_setup, 0x00001a00 ; nop - ; mov r0, vpm ; nop - ; mov r1, vpm ; nop - ; mov ra2, vpm ; nop - ; mov ra3, vpm ; nop - ; nop ; fmul ra0, r0, uniform - ; nop ; fmul ra1, r1, uniform - ; ftoi ra4.16a, ra0, ra0 ; nop - ; ftoi ra4.16b, ra1, ra1 ; nop - ; mov ra5, vpm ; nop - ; mov ra6, vpm ; nop - ; mov ra7, vpm ; nop - ; mov vpm, r0 ; nop - ; mov vpm, r1 ; nop - ; mov vpm, ra2 ; nop - ; mov vpm, ra3 ; nop - ; mov vpm, ra4 ; nop - ; mov vpm, ra2 ; nop - ; mov vpm, ra3 ; nop -thrend ; nop ; nop - ; nop ; nop - ; nop ; nop diff --git a/render-only-sample/Vc4Asm/Tests/fs_3_vary.asm b/render-only-sample/Vc4Asm/Tests/fs_3_vary.asm deleted file mode 100644 index eb7c071..0000000 --- a/render-only-sample/Vc4Asm/Tests/fs_3_vary.asm +++ /dev/null @@ -1,9 +0,0 @@ -loadsm ; mov r0, vary ; mov r3.8d, 1.0 - ; fadd r0, r0, r5 ; mov r1, vary -sbwait ; fadd r1, r1, r5 ; mov r2, vary - ; fadd r2, r2, r5 ; mov r3.8a, r0 - ; nop ; mov r3.8b, r1 - ; nop ; mov r3.8c, r2 -thrend ; mov tlb_c, r3 ; nop - ; nop ; nop -sbdone ; nop ; nop diff --git a/render-only-sample/Vc4Asm/Tests/fs_tex.asm b/render-only-sample/Vc4Asm/Tests/fs_tex.asm deleted file mode 100644 index d00acee..0000000 --- a/render-only-sample/Vc4Asm/Tests/fs_tex.asm +++ /dev/null @@ -1,10 +0,0 @@ - ; mov r0, varying ; nop - ; mov r1, varying ; nop -sbwait ; fadd r2, r0, r5 ; nop - ; fadd r3, r1, r5 ; nop - ; mov tmu0_t, r2 ; nop - ; mov tmu0_s, r3 ; nop -ldtmu0 ; nop ; nop -thrend ; mov tlb_colour, r4 ; nop - ; nop ; nop -sbdone ; nop ; nop diff --git a/render-only-sample/Vc4Asm/Tests/vs_7_vpmread.asm b/render-only-sample/Vc4Asm/Tests/vs_7_vpmread.asm deleted file mode 100644 index 55535e8..0000000 --- a/render-only-sample/Vc4Asm/Tests/vs_7_vpmread.asm +++ /dev/null @@ -1,22 +0,0 @@ -ldi ; mov vr_setup, 0x00701a00 ; nop -ldi ; mov vw_setup, 0x00001a00 ; nop - ; mov r0, vpm ; nop - ; mov r1, vpm ; nop - ; mov ra2, vpm ; nop - ; mov ra3, vpm ; nop - ; nop ; fmul ra0, r0, uniform - ; nop ; fmul ra1, r1, uniform - ; ftoi ra4.16a, ra0, ra0 ; nop - ; ftoi ra4.16b, ra1, ra1 ; nop - ; mov ra5, vpm ; nop - ; mov ra6, vpm ; nop - ; mov ra7, vpm ; nop - ; mov vpm, ra4 ; nop - ; mov vpm, ra2 ; nop - ; mov vpm, ra3 ; nop - ; mov vpm, ra5 ; nop - ; mov vpm, ra6 ; nop - ; mov vpm, ra7 ; nop -thrend ; nop ; nop - ; nop ; nop - ; nop ; nop diff --git a/render-only-sample/Vc4Asm/Vc4Asm.cpp b/render-only-sample/Vc4Asm/Vc4Asm.cpp deleted file mode 100644 index 2b19e5c..0000000 --- a/render-only-sample/Vc4Asm/Vc4Asm.cpp +++ /dev/null @@ -1,933 +0,0 @@ -// Vc4Asm.cpp : Defines the entry point for the console application. -// -// Really simple VC4 QPU Assembler (just enough for verification) - -#include "stdafx.h" - -EXTERN_C void Vc4Disassemble(VC4_QPU_INSTRUCTION *pHwCode, UINT HwCodeSize, fnPrinter Printer); - -TCHAR szAsmFile[MAX_PATH] = { 0 }; - -TCHAR szBuff[4096] = { 0 }; -TCHAR szOriginal[4096] = { 0 }; - -const TCHAR szDelimiters[] = _TEXT(" ,;\n\t"); -const TCHAR szPeriod[] = _TEXT("."); - -#if _DEBUG -#define RETURN_WHEN_INVALID(x,msg,arg,line) if ((x) == VC4_QPU_INVALID_VALUE) { _ftprintf_s(stderr, msg, arg, Line); __debugbreak(); return E_FAIL; } -#define RETURN_ERROR(err,msg,param) _ftprintf_s(stderr, msg, param); __debugbreak(); return err; -#else -#define RETURN_WHEN_INVALID(x,msg,arg,line) if ((x) == VC4_QPU_INVALID_VALUE) { _ftprintf_s(stderr, msg, arg, Line); return E_FAIL; } -#define RETURN_ERROR(err,msg,param) _ftprintf_s(stderr, msg, param); return err; -#endif // _DBG - -INT Vc4_QPU_LookUp_Value(VC4QPU_TOKENLOOKUP_TABLE *pTable, TCHAR *pToken) -{ - for (INT i = 0; pTable[i].Value != VC4_QPU_END_OF_LOOKUPTABLE; i++) - { - TCHAR *pTableToken = pTable[i].Token; - if (pToken[0] != '.' && pTableToken[0] == '.') - { - pTableToken++; - } - if (_tcsicmp(pTableToken, pToken) == 0) - { - return (pTable[i].Value); - } - } - return VC4_QPU_INVALID_VALUE; -} - -INT Vc4_QPU_LookUp_Addr_Value(VC4QPU_TOKENLOOKUP_ADDR_TABLE *pTable, INT Regfile, TCHAR *pToken, boolean *pExchangeable) -{ - for (INT i = 0; pTable[i].LookUp[Regfile].Value != VC4_QPU_END_OF_LOOKUPTABLE; i++) - { - TCHAR *pTableToken = pTable[i].LookUp[Regfile].Token; - if (_tcsicmp(pTableToken, pToken) == 0) - { - if (pExchangeable) - { - *pExchangeable = pTable[i].Exchangeable; - } - return (pTable[i].LookUp[Regfile].Value); - } - } - return VC4_QPU_INVALID_VALUE; -} - -#define VC4_QPU_LOOKUP_VALUE(Type,pToken) Vc4_QPU_LookUp_Value(VC4_QPU_##Type##_LOOKUP, pToken) -#define VC4_QPU_LOOKUP_ADDR_VALUE(Type,Regfile,pToken,pExchangeable) Vc4_QPU_LookUp_Addr_Value(VC4_QPU_##Type##_LOOKUP, Regfile, pToken, pExchangeable) - -INT Vc4_QPU_LookUp_AddOp_ArgCount(INT AddOp) -{ - switch (AddOp) - { - case VC4_QPU_OPCODE_ADD_NOP: - return 0; - case VC4_QPU_OPCODE_ADD_FADD: - case VC4_QPU_OPCODE_ADD_FSUB: - case VC4_QPU_OPCODE_ADD_FMIN: - case VC4_QPU_OPCODE_ADD_FMAX: - case VC4_QPU_OPCODE_ADD_FMIN_ABS: - case VC4_QPU_OPCODE_ADD_FMAX_ABS: - case VC4_QPU_OPCODE_ADD_ADD: - case VC4_QPU_OPCODE_ADD_SUB: - case VC4_QPU_OPCODE_ADD_SHR: - case VC4_QPU_OPCODE_ADD_ASR: - case VC4_QPU_OPCODE_ADD_ROR: - case VC4_QPU_OPCODE_ADD_SHL: - case VC4_QPU_OPCODE_ADD_MIN: - case VC4_QPU_OPCODE_ADD_MAX: - case VC4_QPU_OPCODE_ADD_AND: - case VC4_QPU_OPCODE_ADD_OR: - case VC4_QPU_OPCODE_ADD_XOR: - case VC4_QPU_OPCODE_ADD_V8ADDS: - case VC4_QPU_OPCODE_ADD_V8SUBS: - return 3; // dest, src0, src1 - case VC4_QPU_OPCODE_ADD_FTOI: - case VC4_QPU_OPCODE_ADD_ITOF: - case VC4_QPU_OPCODE_ADD_NOT: - case VC4_QPU_OPCODE_ADD_CLZ: - case VC4_QPU_OPCODE_ADD_MOV: - return 2; // dest, src - default: - assert(false); - } - return -1; -} - -INT Vc4_QPU_LookUp_MulOp_ArgCount(INT MulOp) -{ - switch (MulOp) - { - case VC4_QPU_OPCODE_MUL_NOP: - return 0; - case VC4_QPU_OPCODE_MUL_FMUL: - case VC4_QPU_OPCODE_MUL_MUL24: - case VC4_QPU_OPCODE_MUL_V8MULD: - case VC4_QPU_OPCODE_MUL_V8MIN: - case VC4_QPU_OPCODE_MUL_V8MAX: - case VC4_QPU_OPCODE_MUL_V8ADDS: - case VC4_QPU_OPCODE_MUL_V8SUBS: - return 3; // dest, src0, src1 - case VC4_QPU_OPCODE_MUL_MOV: - return 2; // dest, src - default: - assert(false); - } - return -1; -} - -boolean IsOpEmpty(TCHAR*p, TCHAR **ppNext) -{ - assert(p && ppNext); - - // skip space - while (*p == _TEXT(' ') || *p == _TEXT('\t')) - { - p++; - } - - if (*p == _TEXT(';')) - { - *ppNext = p + 1; - return true; // no opcode found. - } - else - { - TCHAR *pNext = _tcschr(p, _TEXT(';')); - if (pNext) - { - *ppNext = pNext + 1; - } - else - { - pNext = p + _tcslen(p); - } - return false; - } -} - -INT IsPowerOfTwo(UINT n) -{ - return (n && ((n & (n - 1)) == 0)); -} - -INT FindBitPosition(UINT n) -{ - UINT i = 1, pos = 1; - while (!(i & n)) - { - i = i << 1; - ++pos; - } - return pos; -} - -INT ParseSmallImmediate(TCHAR *p) -{ - // TODO: horizontal vetor rotation is not supported. - if (_tcscmp(p, _TEXT("1.0/")) == 0) - { - p += 4; - double value = _tstof(p); - if (value >= 2.0f && value <= 128.0f) - { - UINT IntValue = (UINT)value; - if (value == (double)value) - { - if (IsPowerOfTwo(IntValue)) - { - return 40 + 9 - FindBitPosition(IntValue); // 40 - 47 - } - } - } - } - else if (_tcschr(p, TEXT('.'))) - { - double value = _tstof(p); - if (value >= 1.0f && value <= 128.0f) - { - UINT IntValue = (UINT)value; - if (value == (double)value) - { - if (IsPowerOfTwo(IntValue)) - { - return 31 + FindBitPosition(IntValue); // 32 - 39 - } - } - } - } - else - { - INT value = _tstoi(p); - if (value >= 0 && value <= 15) - { - return value; // 0 - 15 - } - else if (value < 0 && value >= -16) - { - return 32 + value; // 16 - 31 - } - } - - RETURN_ERROR(0, TEXT("Invalid or unsupported small immediate value %s\n"), p); -} - -INT32 ParseImmediate(TCHAR *p) -{ - if (p[0] == NULL) - { - RETURN_ERROR(E_INVALIDARG, TEXT("Missing immediate value, %s\n"), TEXT("NULL")); - } - if ((p[0] == TEXT('0')) && (p[1] == TEXT('x'))) - { - return (INT32)_tcstoul(p, NULL, 16); - } - else if ((p[_tcslen(p)] == TEXT('f')) || (_tcschr(p, TEXT('.')) != NULL)) - { - union { int i; float f; } iandf; - iandf.f = _tcstof(p, NULL); - return (INT32)iandf.i; - } - else - { - return (INT32)_tcstoul(p, NULL, 10); - } -} - -HRESULT ParseALUInstruction(VC4_QPU_INSTRUCTION &QpuInst, TCHAR *pOpCode, UINT Line) -{ - boolean bPackedRegfileA = false; - - boolean bSetFlags = false; - boolean bWriteSwap = false; - boolean bPackUnpackSelect = false; - - INT AddOp = VC4_QPU_OPCODE_ADD_NOP; - INT AddCond = VC4_QPU_COND_ALWAYS; - INT AddArgc = 0; - - INT AddMuxDest = 0; - INT AddWaddr = VC4_QPU_WADDR_NOP; - INT AddPack = 0; - - INT AddMuxSrc[2] = { 0 }; - INT AddRaddr[2] = { VC4_QPU_RADDR_NOP }; - INT AddUnpack[2] = { 0 }; - - boolean AddRegfileExchangeable[3] = { false }; - - INT MulOp = VC4_QPU_OPCODE_MUL_NOP; - INT MulCond = VC4_QPU_COND_ALWAYS; - INT MulArgc = 0; - - INT MulMuxDest = 0; - INT MulWaddr = VC4_QPU_WADDR_NOP; - INT MulPack = 0; - - INT MulMuxSrc[2] = { 0 }; - INT MulRaddr[2] = { VC4_QPU_RADDR_NOP }; - INT MulUnpack[2] = { 0 }; - - boolean MulRegfileExchangeable[3] = { false }; - - boolean bAddReadRegfile_A = false; - boolean bAddReadRegfile_B = false; - - boolean bMulUsePack_A = false; - boolean bAddUsePack_A = false; - - boolean bMulUseUnPack_R4 = false; - boolean bAddUseUnPack_R4 = false; - - INT Pack = 0; // NOP for any packing - INT Unpack = 0; // NOP for any unpacking - - INT RaddrA = VC4_QPU_INVALID_VALUE; - INT RaddrB = VC4_QPU_INVALID_VALUE; - - boolean bSetImmediateValue1 = false; - boolean bSetImmediateValue2 = false; - - INT32 ImmediateValue1 = 0; - INT32 ImmediateValue2 = 0; - - TCHAR *pOpCodeNext; - if (!IsOpEmpty(pOpCode,&pOpCodeNext)) - { - TCHAR *pTokenNext; - TCHAR *pToken = _tcstok_s(pOpCode, szDelimiters, &pTokenNext); - - // Parse instruction - { - TCHAR* _AddCond = NULL; - TCHAR* _AddOp = _tcstok_s(pToken, szPeriod, &_AddCond); - AddOp = VC4_QPU_LOOKUP_VALUE(OPCODE_ADD, _AddOp); - RETURN_WHEN_INVALID(AddOp, TEXT("Invalid AddOp %s, line %d\n"), _AddOp, Line); - AddCond = VC4_QPU_LOOKUP_VALUE(COND, _AddCond); - RETURN_WHEN_INVALID(AddCond, TEXT("Invalid AddOp Cond %s, line %d\n"), _AddCond, Line); - if (VC4_QPU_GET_SIG(QpuInst) == VC4_QPU_SIG_LOAD_IMMEDIATE) - { - if (AddOp != VC4_QPU_OPCODE_ADD_MOV && AddOp != VC4_QPU_OPCODE_ADD_NOP) - { - RETURN_ERROR(E_INVALIDARG, TEXT("Load immediate must be mov instruction, line %d\n"), Line); - } - } - } - - // Parse parameters. - { - AddArgc = Vc4_QPU_LookUp_AddOp_ArgCount(AddOp); - assert(AddArgc <= 3); - TCHAR* _AddArgv[3] = { NULL }; - for (INT i = 0; i < AddArgc; i++) - { - _AddArgv[i] = _tcstok_s(NULL, szDelimiters, &pTokenNext); - } - - // Encode destination and sources - for (INT i = 0; i < AddArgc; i++) - { - TCHAR* _Pack = NULL; - if (i == 0) - { - TCHAR* _Reg = _tcstok_s(_AddArgv[i], szPeriod, &_Pack); - AddWaddr = VC4_QPU_LOOKUP_ADDR_VALUE(WADDR, 0, _Reg, &AddRegfileExchangeable[i]); - if (AddWaddr == VC4_QPU_INVALID_VALUE) - { - // if can't be found on a file, look for b file. - AddWaddr = VC4_QPU_LOOKUP_ADDR_VALUE(WADDR, 1, _Reg, &AddRegfileExchangeable[i]); - RETURN_WHEN_INVALID(AddWaddr, TEXT("Invalid AddOp destination %s, line %d\n"), _Reg, Line); - // AddOp is writing to regfile B. - AddMuxDest = VC4_QPU_ALU_REG_B; - } - else - { - AddMuxDest = VC4_QPU_ALU_REG_A; - } - } - else if (VC4_QPU_GET_SIG(QpuInst) == VC4_QPU_SIG_LOAD_IMMEDIATE) - { - assert(i == 1); - ImmediateValue1 = ParseImmediate(_AddArgv[i]); - bSetImmediateValue1 = true; - } - else - { - TCHAR* _Reg = _tcstok_s(_AddArgv[i], szPeriod, &_Pack); - AddMuxSrc[i-1] = VC4_QPU_LOOKUP_VALUE(ALU, _Reg); - if (AddMuxSrc[i-1] == VC4_QPU_INVALID_VALUE) - { - AddRaddr[i-1] = VC4_QPU_LOOKUP_ADDR_VALUE(RADDR, 0, _Reg, &AddRegfileExchangeable[i]); - if (AddRaddr[i-1] == VC4_QPU_INVALID_VALUE) - { - AddRaddr[i-1] = VC4_QPU_LOOKUP_ADDR_VALUE(RADDR, 1, _Reg, &AddRegfileExchangeable[i]); - RETURN_WHEN_INVALID(AddRaddr[i-1], TEXT("Invalid AddOp source %s, line %d\n"), _Reg, Line); - // AddOp is reading from Regfile B - AddMuxSrc[i-1] = VC4_QPU_ALU_REG_B; - bAddReadRegfile_B = true; - } - else - { - // AddOp is reading from Regfile A - AddMuxSrc[i-1] = VC4_QPU_ALU_REG_A; - bAddReadRegfile_A = true; - } - } - } - - if (_Pack && _Pack[0]) - { - if (i == 0) // Pack - { - if (AddMuxDest != VC4_QPU_ALU_REG_A) - { - RETURN_ERROR(E_FAIL, TEXT("Pack can be only used to write regfile A at AddOps, line %d\n"), Line); - } - AddPack = VC4_QPU_LOOKUP_VALUE(PACK_A, _Pack); - RETURN_WHEN_INVALID(AddPack, TEXT("Invalid pack at AddOps %s, line %d\n"), _Pack, Line); - } - else // Unpack - { - AddUnpack[i-1] = VC4_QPU_LOOKUP_VALUE(PACK_A, _Pack); - RETURN_WHEN_INVALID(AddUnpack[i-1], TEXT("Invalid pack at AddOps %s, line %d\n"), _Pack, Line); - bAddUseUnPack_R4 = (AddMuxSrc[i-1] == VC4_QPU_ALU_R4) ? true : false; - } - } - } - } - } - - pOpCode = pOpCodeNext; - if (!IsOpEmpty(pOpCode, &pOpCodeNext)) - { - TCHAR *pTokenNext; - TCHAR *pToken = _tcstok_s(pOpCode, szDelimiters, &pTokenNext); - - // Parse instruction - { - TCHAR* _MulCond = NULL; - TCHAR* _MulOp = _tcstok_s(pToken, szPeriod, &_MulCond); - MulOp = VC4_QPU_LOOKUP_VALUE(OPCODE_MUL, _MulOp); - RETURN_WHEN_INVALID(MulOp, TEXT("Invalid MulOp %s, line %d\n"), _MulOp, Line); - MulCond = VC4_QPU_LOOKUP_VALUE(COND, _MulCond); - RETURN_WHEN_INVALID(MulCond, TEXT("Invalid AddOp Cond %s, line %d\n"), _MulCond, Line); - if (VC4_QPU_GET_SIG(QpuInst) == VC4_QPU_SIG_LOAD_IMMEDIATE) - { - if (MulOp != VC4_QPU_OPCODE_MUL_MOV && MulOp != VC4_QPU_OPCODE_MUL_NOP) - { - RETURN_ERROR(E_INVALIDARG, TEXT("Load immediate must be mov instruction, line %d\n"), Line); - } - } - } - - // Parse parameters. - { - MulArgc = (VC4_QPU_GET_SIG(QpuInst) == VC4_QPU_SIG_ALU_WITH_RADDR_B) ? 2 : Vc4_QPU_LookUp_MulOp_ArgCount(MulOp); - assert(MulArgc <= 3); - TCHAR* _MulArgv[3] = { NULL }; - for (INT i = 0; i < MulArgc; i++) - { - _MulArgv[i] = _tcstok_s(NULL, szDelimiters, &pTokenNext); - } - - // Encode destination and sources - for (INT i = 0; i < MulArgc; i++) - { - TCHAR* _Pack = NULL; - if (i == 0) - { - TCHAR* _Reg = _tcstok_s(_MulArgv[i], szPeriod, &_Pack); - MulWaddr = VC4_QPU_LOOKUP_ADDR_VALUE(WADDR, 1, _Reg, &MulRegfileExchangeable[i]); - if (MulWaddr == VC4_QPU_INVALID_VALUE) - { - MulWaddr = VC4_QPU_LOOKUP_ADDR_VALUE(WADDR, 0, _Reg, &MulRegfileExchangeable[i]); - RETURN_WHEN_INVALID(MulWaddr, TEXT("Invalid MulOp destination %s, line %d\n"), _Reg, Line); - MulMuxDest = VC4_QPU_ALU_REG_A; - } - else - { - MulMuxDest = VC4_QPU_ALU_REG_B; - } - } - else if (VC4_QPU_GET_SIG(QpuInst) == VC4_QPU_SIG_ALU_WITH_RADDR_B) - { - assert(i == 1); - MulMuxSrc[i-1] = VC4_QPU_ALU_REG_B; - MulRaddr[i-1] = ParseSmallImmediate(_MulArgv[i]); - } - else if (VC4_QPU_GET_SIG(QpuInst) == VC4_QPU_SIG_LOAD_IMMEDIATE) - { - assert(i == 1); - ImmediateValue2 = ParseImmediate(_MulArgv[i]); - bSetImmediateValue2 = true; - } - else - { - TCHAR* _Reg = _tcstok_s(_MulArgv[i], szPeriod, &_Pack); - MulMuxSrc[i-1] = VC4_QPU_LOOKUP_VALUE(ALU, _Reg); - if (MulMuxSrc[i-1] == VC4_QPU_INVALID_VALUE) - { - // If AddOps already took regfile A, try B first, otherwise A first. - MulRaddr[i-1] = VC4_QPU_LOOKUP_ADDR_VALUE(RADDR, bAddReadRegfile_A ? 1 : 0, _Reg, &MulRegfileExchangeable[i]); - if (MulRaddr[i-1] == VC4_QPU_INVALID_VALUE) - { - MulRaddr[i-1] = VC4_QPU_LOOKUP_ADDR_VALUE(RADDR, bAddReadRegfile_A ? 0 : 1, _Reg, &MulRegfileExchangeable[i]); - RETURN_WHEN_INVALID(MulRaddr[i-1], TEXT("Invalid MulOp source %s, line %d\n"), _Reg, Line); - MulMuxSrc[i-1] = bAddReadRegfile_A ? VC4_QPU_ALU_REG_A : VC4_QPU_ALU_REG_B; - } - else - { - MulMuxSrc[i-1] = bAddReadRegfile_A ? VC4_QPU_ALU_REG_B : VC4_QPU_ALU_REG_A; - } - } - } - - if (_Pack && _Pack[0]) - { - if (i == 0) // Pack - { - // Try MulOp unpack first. - MulPack = VC4_QPU_LOOKUP_VALUE(PACK_MUL, _Pack); - if (MulPack == VC4_QPU_INVALID_VALUE) - { - // if not, then see regfile A pack, only if writing to regfile A. - if (MulMuxDest == VC4_QPU_ALU_REG_A) - { - MulPack = VC4_QPU_LOOKUP_VALUE(PACK_A, _Pack); - bMulUsePack_A = true; - } - } - RETURN_WHEN_INVALID(MulPack, TEXT("Invalid pack at MulOps %s, line %d\n"), _Pack, Line); - } - else // Unpack - { - MulUnpack[i-1] = VC4_QPU_LOOKUP_VALUE(PACK_A, _Pack); - RETURN_WHEN_INVALID(MulUnpack[i-1], TEXT("Invalid pack at AddOps %s, line %d\n"), _Pack, Line); - bMulUseUnPack_R4 = (MulMuxSrc[i-1] == VC4_QPU_ALU_R4) ? true : false; - } - } - } - } - } - - // Remap "mov" to proper opcode. - if (AddOp == VC4_QPU_OPCODE_ADD_MOV) - { - AddOp = VC4_QPU_OPCODE_ADD_OR; - } - if (MulOp == VC4_QPU_OPCODE_MUL_MOV) - { - MulOp = VC4_QPU_OPCODE_MUL_V8MIN; - } - - // If OpCode is NOP, condition is changed to never. - if (AddOp == VC4_QPU_OPCODE_ADD_NOP) - { - AddCond = VC4_QPU_COND_NEVER; - } - if (MulOp == VC4_QPU_OPCODE_MUL_NOP) - { - MulCond = VC4_QPU_COND_NEVER; - } - - // Any instruction only with 2 parameters, copy [1] to [2]. - if (AddArgc <= 2) - { - AddMuxSrc[1] = AddMuxSrc[0]; - AddRaddr[1] = AddRaddr[0]; - AddUnpack[1] = AddUnpack[0]; - } - if (MulArgc <= 2) - { - MulMuxSrc[1] = MulMuxSrc[0]; - MulRaddr[1] = MulRaddr[0]; - MulUnpack[1] = MulUnpack[0]; - } - - // If Signature is load_sm, then MulOp must be 'mov' - if ((VC4_QPU_GET_SIG(QpuInst) == VC4_QPU_SIG_ALU_WITH_RADDR_B) && - (MulOp != VC4_QPU_OPCODE_MUL_V8MIN)) - { - RETURN_ERROR(E_FAIL, _TEXT("load_sm sig must have 'mov' or 'or' at MulOp, line %d\n"), Line); - } - - // AddOp and MulOp can't write to same location. - if ((AddMuxDest == MulMuxDest) && - (AddWaddr == MulWaddr) && AddRegfileExchangeable[0]) - { - RETURN_ERROR(E_FAIL, _TEXT("Both of AddOp and MulOp writes to same destination, line %d\n"), Line); - } - - // Determine who to use regfile A destination. - // First, check who uses regfile A pack. - if (AddPack && bMulUsePack_A) - { - RETURN_ERROR(E_FAIL, _TEXT("Both of AddOp and MulOp use regfile A pack, line %d\n"), Line); - } - else if (AddPack == 0 && bMulUsePack_A) - { - // MulOp wants to write regfile A pack - } - else if (AddPack) - { - assert(bMulUsePack_A == false); - // AddOp wants to write regfile A pack. - bAddUsePack_A = true; - } - assert((bAddUsePack_A && bMulUsePack_A) == false); - - if ((MulPack && (bMulUsePack_A == false)) && bAddUsePack_A) - { - RETURN_ERROR(E_FAIL, _TEXT("Mul pack and Regfile A pack can't be use at same time, line %d\n"), Line); - } - - if ((bMulUseUnPack_R4 || bAddUseUnPack_R4 || bAddUsePack_A || bMulUsePack_A) && - (bMulUseUnPack_R4 || bAddUseUnPack_R4) == (bAddUsePack_A || bMulUsePack_A)) - { - RETURN_ERROR(E_FAIL, _TEXT("R4 unpack and Regfile A pack can't be use at same time, line %d\n"), Line); - } - - if (bAddUsePack_A && (AddMuxDest != VC4_QPU_ALU_REG_A)) - { - RETURN_ERROR(E_FAIL, _TEXT("AddOp wants to use regfile A pack, but it's not writing to regfile A, line %d\n"), Line); - } - - if (bMulUsePack_A && (MulMuxDest != VC4_QPU_ALU_REG_A)) - { - RETURN_ERROR(E_FAIL, _TEXT("AddOp wants to use regfile A pack, but it's not writing to regfile A, line %d\n"), Line); - -// TODO: regfile reassignment. -// if (!MulRegfileExchangeable[0]) -// { -// RETURN_ERROR(E_FAIL, _TEXT("MulOp wants to use regfile A pack, but it's writing to regfile only available on B, line %d\n"), Line); -// } - } - - if (MulPack && (bMulUsePack_A == false)) - { - // MulPack is used, set PM bit. - bPackUnpackSelect = true; - Pack = MulPack; - } - else if (bMulUseUnPack_R4 || bAddUseUnPack_R4) - { - bPackUnpackSelect = true; - } - else if (AddPack) - { - assert(bPackUnpackSelect == false); - Pack = AddPack; - } - - // Validate Unpack. - if (VC4_QPU_GET_SIG(QpuInst) != VC4_QPU_SIG_LOAD_IMMEDIATE) - { - INT _Mux[4] = { AddMuxSrc[0], AddMuxSrc[1], MulMuxSrc[0], MulMuxSrc[1] }; - INT _Unpack[4] = { AddUnpack[0], AddUnpack[1], MulUnpack[0], MulUnpack[1] }; - for (INT _i = 0; _i < 4; _i++) - { - if (Unpack != 0 && Unpack != _Unpack[_i]) - { - RETURN_ERROR(E_FAIL, _TEXT("Unpack is not consistent, line %d\n"), Line); - } - if (_Unpack[_i]) - { - if (bPackUnpackSelect && _Mux[_i] != VC4_QPU_ALU_R4) - { - // when PM bit set, only r4 unpack can be performed. - RETURN_ERROR(E_FAIL, _TEXT("Only r4 can perform unpack with PM bit set, line %d\n"), Line); - } - Unpack = _Unpack[_i]; - } - } - } - - // Set and validate RaddrA/B. - if (VC4_QPU_GET_SIG(QpuInst) != VC4_QPU_SIG_LOAD_IMMEDIATE) - { - INT _Mux[4] = { AddMuxSrc[0], AddMuxSrc[1], MulMuxSrc[0], MulMuxSrc[1] }; - INT _Raddr[4] = { AddRaddr[0], AddRaddr[1], MulRaddr[0], MulRaddr[1] }; - for (INT _i = 0; _i < 4; _i++) - { - if (_Mux[_i] == VC4_QPU_ALU_REG_A) - { - if (_Raddr[_i] != VC4_QPU_RADDR_NOP && (RaddrA != _Raddr[_i])) - { - if (RaddrA == VC4_QPU_INVALID_VALUE) - { - RaddrA = _Raddr[_i]; - } - else - { - RETURN_ERROR(E_FAIL, _TEXT("Conflit usage for RaddrA, line %d"), Line); - } - } - } - else if (_Mux[_i] == VC4_QPU_ALU_REG_B) - { - if (_Raddr[_i] != VC4_QPU_RADDR_NOP && (RaddrB != _Raddr[_i])) - { - if (RaddrB == VC4_QPU_INVALID_VALUE) - { - RaddrB = _Raddr[_i]; - } - else - { - RETURN_ERROR(E_FAIL, _TEXT("Conflit usage for RaddrB, line %d"), Line); - } - } - } - } - - if (RaddrA == VC4_QPU_INVALID_VALUE) - { - RaddrA = VC4_QPU_RADDR_NOP; - } - if (RaddrB == VC4_QPU_INVALID_VALUE) - { - RaddrB = VC4_QPU_RADDR_NOP; - } - } - - // Set write swap, - bWriteSwap = (AddMuxDest == VC4_QPU_ALU_REG_B) || (MulMuxDest == VC4_QPU_ALU_REG_A); - - // TODO: - bSetFlags = false; - - // Build instruction - if (VC4_QPU_GET_SIG(QpuInst) == VC4_QPU_SIG_LOAD_IMMEDIATE) - { - if (bSetImmediateValue1 && bSetImmediateValue2 && (ImmediateValue1 != ImmediateValue2)) - { - RETURN_ERROR(E_INVALIDARG, TEXT("ImmedicateValue is not consistent, Line %d\n"), Line); - } - VC4_QPU_SET_IMMEDIATE_TYPE(QpuInst, VC4_QPU_IMMEDIATE_TYPE_32); - VC4_QPU_SET_PM(QpuInst, bPackUnpackSelect); - VC4_QPU_SET_PACK(QpuInst, Pack); - VC4_QPU_SET_COND_ADD(QpuInst, AddCond); - VC4_QPU_SET_COND_MUL(QpuInst, MulCond); - VC4_QPU_SET_SETFLAGS(QpuInst, bSetFlags); - VC4_QPU_SET_WRITESWAP(QpuInst, bWriteSwap); - VC4_QPU_SET_WADDR_ADD(QpuInst, AddWaddr); - VC4_QPU_SET_WADDR_MUL(QpuInst, MulWaddr); - VC4_QPU_SET_IMMEDIATE_32(QpuInst, ImmediateValue1 ? ImmediateValue1 : ImmediateValue2); - } - else - { - VC4_QPU_SET_UNPACK(QpuInst, Unpack); - VC4_QPU_SET_PM(QpuInst, bPackUnpackSelect); - VC4_QPU_SET_PACK(QpuInst, Pack); - VC4_QPU_SET_COND_ADD(QpuInst, AddCond); - VC4_QPU_SET_COND_MUL(QpuInst, MulCond); - VC4_QPU_SET_SETFLAGS(QpuInst, bSetFlags); - VC4_QPU_SET_WRITESWAP(QpuInst, bWriteSwap); - VC4_QPU_SET_WADDR_ADD(QpuInst, AddWaddr); - VC4_QPU_SET_WADDR_MUL(QpuInst, MulWaddr); - VC4_QPU_SET_OPCODE_ADD(QpuInst, AddOp); - VC4_QPU_SET_OPCODE_MUL(QpuInst, MulOp); - VC4_QPU_SET_RADDR_A(QpuInst, RaddrA); - VC4_QPU_SET_RADDR_B(QpuInst, RaddrB); - VC4_QPU_SET_ADD_A(QpuInst, AddMuxSrc[0]); - VC4_QPU_SET_ADD_B(QpuInst, AddMuxSrc[1]); - VC4_QPU_SET_MUL_A(QpuInst, MulMuxSrc[0]); - VC4_QPU_SET_MUL_B(QpuInst, MulMuxSrc[1]); - } - - return S_OK; -} - -void Printer(void *pFile, const TCHAR* szStr, int Line, void* m_pCustomCtx) -{ - _ftprintf_s(stderr, TEXT("// %s"), szStr); -} - -int _tmain(int argc, TCHAR *argv[]) -{ - boolean ShowDisassemble = false; - boolean ShowOriginal = false; - boolean Disassemble = false; - - if (argc <= 1) - { - RETURN_ERROR(E_INVALIDARG, _TEXT("%s\n"), TEXT("Usage: Vc4Asm ASMFile [OUTFile]\n")); - } - - for (int i = 1; i < argc; i++) - { - if (*argv[i] == TEXT('-')) - { - if (_tcsicmp(argv[i], TEXT("-ShowDisassemble")) == 0) - { - ShowDisassemble = true; - } - else if (_tcsicmp(argv[i], TEXT("-ShowOriginal")) == 0) - { - ShowOriginal = true; - } - else if (_tcsicmp(argv[i], TEXT("-Disassemble")) == 0) - { - Disassemble = true; - } - else - { - RETURN_ERROR(E_INVALIDARG, _TEXT("Invalid Option %s\n"), argv[i]); - } - } - else if (szAsmFile[0] == NULL) - { - _tcscpy_s(szAsmFile, argv[i]); - } - else - { - RETURN_ERROR(E_INVALIDARG, TEXT("Invalid argument - %s\n"), argv[i]); - } - } - - FILE* fpASM = NULL; - - errno_t err = _tfopen_s(&fpASM, szAsmFile, _TEXT("r")); - if (err) - { - RETURN_ERROR(E_INVALIDARG, TEXT("Invalid Asm file - %s\n"), szAsmFile); - } - - UINT Line = 0; - HRESULT hr = S_OK; - while (_fgetts(szBuff, _countof(szBuff), fpASM) && (hr == S_OK)) - { - VC4_QPU_INSTRUCTION QpuInst = 0; - Line++; - - if (Disassemble) - { - TCHAR *pTokenNext = NULL; - TCHAR *pValue = _tcstok_s(szBuff, szDelimiters, &pTokenNext); - do - { - INT c = 0; - if (pValue[0] == '0' && pValue[1] == 'x') - { - c += 2; // Skip 0x. - } - - size_t cLen = _tcslen(pValue); - if (cLen == 16 + c) - { - if (QpuInst) - { - _ftprintf_s(stderr, TEXT("Invalid immediate format %s, line %d\n"), pValue, Line); - hr = E_INVALIDARG; - break; - } - QpuInst = (VC4_QPU_INSTRUCTION) _tcstoull(pValue, NULL, 16); - break; - } - else if (cLen == 8 + c) - { - VC4_QPU_INSTRUCTION value = (VC4_QPU_INSTRUCTION) _tcstoul(pValue, NULL, 16); - if (QpuInst) - { - assert((0xffffffff00000000ULL & QpuInst) == 0); - QpuInst |= (value << 32); - break; - } - else - { - QpuInst = value; - } - pValue = _tcstok_s(NULL, szDelimiters, &pTokenNext); - } - else - { - _ftprintf_s(stderr, TEXT("Invalid immediate format %s, line %d\n"), pValue, Line); - hr = E_INVALIDARG; - break; - } - } - while (true); - } - else - { - // Copy original before token break it. - _tcscpy_s(szOriginal, szBuff); - - // Parse Signature if provided. - UINT Sig = VC4_QPU_SIG_NO_SIGNAL; - TCHAR *pOpCodeNext = NULL; - if (!IsOpEmpty(szBuff, &pOpCodeNext)) - { - TCHAR *pTokenNext; - TCHAR *pToken = _tcstok_s(szBuff, szDelimiters, &pTokenNext); - - // Parse Signature if provided. - Sig = VC4_QPU_LOOKUP_VALUE(SIG, pToken); - if (Sig == VC4_QPU_INVALID_VALUE) - { - _ftprintf_s(stderr, TEXT("Invalid Signature %s, line %d\n"), pToken, Line); - break; - } - } - VC4_QPU_SET_SIG(QpuInst, Sig); - - switch (Sig) - { - case VC4_QPU_SIG_BREAK: - case VC4_QPU_SIG_NO_SIGNAL: - case VC4_QPU_SIG_THREAD_SWITCH: - case VC4_QPU_SIG_PROGRAM_END: - case VC4_QPU_SIG_WAIT_FOR_SCOREBOARD: - case VC4_QPU_SIG_SCOREBOARD_UNBLOCK: - case VC4_QPU_SIG_LAST_THREAD_SWITCH: - case VC4_QPU_SIG_COVERAGE_LOAD: - case VC4_QPU_SIG_COLOR_LOAD: - case VC4_QPU_SIG_COLOR_LOAD_AND_PROGRAM_END: - case VC4_QPU_SIG_LOAD_TMU0: - case VC4_QPU_SIG_LOAD_TMU1: - case VC4_QPU_SIG_ALPAH_MASK_LOAD: - case VC4_QPU_SIG_ALU_WITH_RADDR_B: - case VC4_QPU_SIG_LOAD_IMMEDIATE: - hr = ParseALUInstruction(QpuInst, pOpCodeNext, Line); - break; - case VC4_QPU_SIG_BRANCH: - _ftprintf_s(stderr, TEXT("Branch is not supported, line %d\n"), Line); - hr = E_NOTIMPL; - default: - assert(false); // this should never happen. - break; - } - - if (hr == S_OK) - { - _ftprintf_s(stdout, TEXT("0x%016llx,\t"), QpuInst); - if (ShowOriginal) - { - TCHAR *p = _tcschr(szOriginal, TEXT('\n')); - if (p) *p = NULL; - _ftprintf_s(stdout, TEXT("// %s \t"), szOriginal); - } - } - else - { - break; - } - } - - if ((hr == S_OK) && (ShowDisassemble || Disassemble)) - { - Vc4Disassemble(&QpuInst, sizeof(QpuInst), Printer); - } - _ftprintf(stdout, TEXT("\n")); - } - - if (fpASM) - { - fclose(fpASM); - } - - return 0; -} - diff --git a/render-only-sample/Vc4Asm/Vc4Asm.vcxproj b/render-only-sample/Vc4Asm/Vc4Asm.vcxproj deleted file mode 100644 index 0a53f8c..0000000 --- a/render-only-sample/Vc4Asm/Vc4Asm.vcxproj +++ /dev/null @@ -1,172 +0,0 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - Debug - x64 - - - Release - x64 - - - - {53098D78-1666-4AE9-AAEA-15EC43D787B0} - Win32Proj - Vc4Asm - 10.0.10586.0 - - - - Application - true - v140 - Unicode - - - Application - false - v140 - true - Unicode - - - Application - true - v140 - Unicode - - - Application - false - v140 - true - Unicode - - - - - - - - - - - - - - - - - - - - - true - - - true - - - false - - - false - - - - Use - Level3 - Disabled - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - - - Console - true - roscompiler.lib;%(AdditionalDependencies) - $(OutDir) - - - - - Use - Level3 - Disabled - _DEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - - - Console - true - roscompiler.lib;%(AdditionalDependencies) - $(OutDir) - - - - - Level3 - Use - MaxSpeed - true - true - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - - - Console - true - true - true - roscompiler.lib;%(AdditionalDependencies) - $(OutDir) - - - - - Level3 - Use - MaxSpeed - true - true - NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - - - Console - true - true - true - roscompiler.lib;%(AdditionalDependencies) - $(OutDir) - - - - - - - - - - - - - Create - Create - Create - Create - - - - - - - \ No newline at end of file diff --git a/render-only-sample/Vc4Asm/Vc4Asm.vcxproj.filters b/render-only-sample/Vc4Asm/Vc4Asm.vcxproj.filters deleted file mode 100644 index 27aa951..0000000 --- a/render-only-sample/Vc4Asm/Vc4Asm.vcxproj.filters +++ /dev/null @@ -1,42 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hh;hpp;hxx;hm;inl;inc;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - {d7425d49-578d-4888-b648-d00c788ce17d} - - - - - - - - Header Files - - - Header Files - - - Common - - - - - Source Files - - - Source Files - - - \ No newline at end of file diff --git a/render-only-sample/Vc4Asm/stdafx.cpp b/render-only-sample/Vc4Asm/stdafx.cpp deleted file mode 100644 index ca0e010..0000000 --- a/render-only-sample/Vc4Asm/stdafx.cpp +++ /dev/null @@ -1,8 +0,0 @@ -// stdafx.cpp : source file that includes just the standard includes -// Vc4Asm.pch will be the pre-compiled header -// stdafx.obj will contain the pre-compiled type information - -#include "stdafx.h" - -// TODO: reference any additional headers you need in STDAFX.H -// and not in this file diff --git a/render-only-sample/Vc4Asm/stdafx.h b/render-only-sample/Vc4Asm/stdafx.h deleted file mode 100644 index 1827937..0000000 --- a/render-only-sample/Vc4Asm/stdafx.h +++ /dev/null @@ -1,21 +0,0 @@ -// stdafx.h : include file for standard system include files, -// or project specific include files that are used frequently, but -// are changed infrequently -// - -#pragma once - -#include "targetver.h" - -#include -#include -#include - -#include - -#define VC4 1 -#include "..\roscommon\Vc4Qpu.h" -#include "..\roscompiler\DisasmBase.hpp" -#include "..\roscompiler\Vc4Disasm.hpp" - -// TODO: reference additional headers your program requires here diff --git a/render-only-sample/Vc4Asm/targetver.h b/render-only-sample/Vc4Asm/targetver.h deleted file mode 100644 index 87c0086..0000000 --- a/render-only-sample/Vc4Asm/targetver.h +++ /dev/null @@ -1,8 +0,0 @@ -#pragma once - -// Including SDKDDKVer.h defines the highest available Windows platform. - -// If you wish to build your application for a previous Windows platform, include WinSDKVer.h and -// set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h. - -#include diff --git a/render-only-sample/demos/CubeTestUwp/Common/DeviceResources.cpp b/render-only-sample/demos/CubeTestUwp/Common/DeviceResources.cpp index fcca2fb..bf7adab 100644 --- a/render-only-sample/demos/CubeTestUwp/Common/DeviceResources.cpp +++ b/render-only-sample/demos/CubeTestUwp/Common/DeviceResources.cpp @@ -158,8 +158,6 @@ void DX::DeviceResources::CreateDeviceResources() // Create the Direct3D 11 API device object and a corresponding context. ComPtr device; ComPtr context; - - Sleep(10000); HRESULT hr = D3D11CreateDevice( nullptr, // Specify nullptr to use the default adapter. @@ -252,7 +250,7 @@ void DX::DeviceResources::CreateWindowSizeDependentResources() 2, // Double-buffered swap chain. lround(m_d3dRenderTargetSize.Width), lround(m_d3dRenderTargetSize.Height), - DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_B8G8R8A8_UNORM, 0 ); @@ -278,7 +276,7 @@ void DX::DeviceResources::CreateWindowSizeDependentResources() swapChainDesc.Width = lround(m_d3dRenderTargetSize.Width); // Match the size of the window. swapChainDesc.Height = lround(m_d3dRenderTargetSize.Height); - swapChainDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; // This is the most common swap chain format. + swapChainDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM; // This is the most common swap chain format. swapChainDesc.Stereo = false; swapChainDesc.SampleDesc.Count = 1; // Don't use multi-sampling. swapChainDesc.SampleDesc.Quality = 0; @@ -425,7 +423,7 @@ void DX::DeviceResources::CreateWindowSizeDependentResources() D2D1_BITMAP_PROPERTIES1 bitmapProperties = D2D1::BitmapProperties1( D2D1_BITMAP_OPTIONS_TARGET | D2D1_BITMAP_OPTIONS_CANNOT_DRAW, - D2D1::PixelFormat(DXGI_FORMAT_R8G8B8A8_UNORM, D2D1_ALPHA_MODE_PREMULTIPLIED), + D2D1::PixelFormat(DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_PREMULTIPLIED), m_dpi, m_dpi ); diff --git a/render-only-sample/demos/DolphinUniversal/Common/DeviceResources.cpp b/render-only-sample/demos/DolphinUniversal/Common/DeviceResources.cpp index e510088..f49fa87 100644 --- a/render-only-sample/demos/DolphinUniversal/Common/DeviceResources.cpp +++ b/render-only-sample/demos/DolphinUniversal/Common/DeviceResources.cpp @@ -130,13 +130,13 @@ void DX::DeviceResources::CreateDeviceResources() // than the API default. It is required for compatibility with Direct2D. UINT creationFlags = D3D11_CREATE_DEVICE_BGRA_SUPPORT; -#if defined(_DEBUG) - if (DX::SdkLayersAvailable()) - { - // If the project is in a debug build, enable debugging via SDK Layers with this flag. - creationFlags |= D3D11_CREATE_DEVICE_DEBUG; - } -#endif +// #if defined(_DEBUG) + // if (DX::SdkLayersAvailable()) + // { + // // If the project is in a debug build, enable debugging via SDK Layers with this flag. + // creationFlags |= D3D11_CREATE_DEVICE_DEBUG; + // } +// #endif // This array defines the set of DirectX hardware feature levels this app will support. // Note the ordering should be preserved. diff --git a/render-only-sample/roscommon/RosLogging.h b/render-only-sample/roscommon/RosLogging.h new file mode 100644 index 0000000..3af1f9a --- /dev/null +++ b/render-only-sample/roscommon/RosLogging.h @@ -0,0 +1,98 @@ +#ifndef _ROSLOGGING_H_ +#define _ROSLOGGING_H_ 1 + +// +// Copyright (C) Microsoft. All rights reserved. +// +// WPP tracing configuration file shared between usermode and kernel mode. +// + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +// +// Debug/Bugcheck helpers used by tracing macros. +// NOTE: These are not intended to be called from anywhere else +// +extern int _RosLogBugcheck (ULONG Level); +extern int _RosLogDebug (ULONG Level); + +// begin_wpp config +// +// FUNC ROS_LOG_CRITICAL_ERROR{LEVEL=TRACE_LEVEL_CRITICAL, FLAGS=ROS_TRACING_BUGCHECK}(MSG, ...); +// USEPREFIX (ROS_LOG_CRITICAL_ERROR, "%!STDPREFIX! [%s @ %u] CRITICAL ERROR:", __FILE__, __LINE__); +// +// FUNC ROS_LOG_ASSERTION{LEVEL=TRACE_LEVEL_ERROR, FLAGS=ROS_TRACING_DEBUG}(MSG, ...); +// USEPREFIX (ROS_LOG_ASSERTION, "%!STDPREFIX! [%s @ %u] ASSERTION :", __FILE__, __LINE__); +// +// FUNC ROS_LOG_ERROR{LEVEL=TRACE_LEVEL_ERROR, FLAGS=ROS_TRACING_DEFAULT}(MSG, ...); +// USEPREFIX (ROS_LOG_ERROR, "%!STDPREFIX! [%s @ %u] ERROR :", __FILE__, __LINE__); +// +// FUNC ROS_LOG_LOW_MEMORY{LEVEL=TRACE_LEVEL_ERROR, FLAGS=ROS_TRACING_DEFAULT}(MSG, ...); +// USEPREFIX (ROS_LOG_LOW_MEMORY, "%!STDPREFIX! [%s @ %u] LOW MEMORY :", __FILE__, __LINE__); +// +// FUNC ROS_LOG_WARNING{LEVEL=TRACE_LEVEL_WARNING, FLAGS=ROS_TRACING_DEFAULT}(MSG, ...); +// USEPREFIX (ROS_LOG_WARNING, "%!STDPREFIX! [%s @ %u] WARNING :", __FILE__, __LINE__); +// +// FUNC ROS_LOG_INFORMATION{LEVEL=TRACE_LEVEL_INFORMATION, FLAGS=ROS_TRACING_DEFAULT}(MSG, ...); +// USEPREFIX (ROS_LOG_INFORMATION, "%!STDPREFIX! [%s @ %u] INFO :", __FILE__, __LINE__); +// +// FUNC ROS_LOG_TRACE{LEVEL=TRACE_LEVEL_VERBOSE, FLAGS=ROS_TRACING_DEFAULT}(MSG, ...); +// USEPREFIX (ROS_LOG_TRACE, "%!STDPREFIX! [%s @ %u] TRACE :", __FILE__, __LINE__); +// +// FUNC ROS_TRACE_EVENTS(LEVEL, FLAGS, MSG, ...); +// USEPREFIX (ROS_TRACE_EVENTS, "%!STDPREFIX! [%s @ %u] TRACE :", __FILE__, __LINE__); +// +// FUNC ROS_CRITICAL_ASSERT{LEVEL=TRACE_LEVEL_CRITICAL, FLAGS=ROS_TRACING_BUGCHECK}(ROS_CRIT_ASSERT_EXP); +// USEPREFIX (ROS_CRITICAL_ASSERT, "%!STDPREFIX! [%s @ %u] CRITICAL ASSERTION :%s", __FILE__, __LINE__, #ROS_CRIT_ASSERT_EXP); +// +// FUNC ROS_ASSERT{LEVEL=TRACE_LEVEL_ERROR, FLAGS=ROS_TRACING_DEBUG}(ROS_ASSERT_EXP); +// USEPREFIX (ROS_ASSERT, "%!STDPREFIX! [%s @ %u] ASSERTION :%s", __FILE__, __LINE__, #ROS_ASSERT_EXP); +// +// end_wpp + + +// +// ROS_LOG... customization +// + +#define WPP_LEVEL_FLAGS_POST(LEVEL,FLAGS) \ + ,(((WPP_BIT_ ## FLAGS) == WPP_BIT_ROS_TRACING_BUGCHECK) ? \ + _RosLogBugcheck(LEVEL) : \ + (((WPP_BIT_ ## FLAGS) == WPP_BIT_ROS_TRACING_DEBUG) ? \ + _RosLogDebug(LEVEL) : 1)) + +// +// ROS_CRTITICAL_ASSERT customization +// + +#define WPP_RECORDER_LEVEL_FLAGS_ROS_CRIT_ASSERT_EXP_FILTER(LEVEL, FLAGS, ROS_CRIT_ASSERT_EXP) \ + (!(ROS_CRIT_ASSERT_EXP)) + +#define WPP_RECORDER_LEVEL_FLAGS_ROS_CRIT_ASSERT_EXP_ARGS(LEVEL, FLAGS, ROS_CRIT_ASSERT_EXP) \ + WPP_CONTROL(WPP_BIT_ ## FLAGS).AutoLogContext, LEVEL, WPP_BIT_ ## FLAGS + +#define WPP_LEVEL_FLAGS_ROS_CRIT_ASSERT_EXP_POST(LEVEL, FLAGS, ROS_CRIT_ASSERT_EXP) \ + ,((!(ROS_CRIT_ASSERT_EXP)) ? _RosLogBugcheck(LEVEL) : 1) + +// +// ROS_ASSERT customization +// + +#define WPP_RECORDER_LEVEL_FLAGS_ROS_ASSERT_EXP_FILTER(LEVEL, FLAGS, ROS_ASSERT_EXP) \ + (!(ROS_ASSERT_EXP)) + +#define WPP_RECORDER_LEVEL_FLAGS_ROS_ASSERT_EXP_ARGS(LEVEL, FLAGS, ROS_ASSERT_EXP) \ + WPP_CONTROL(WPP_BIT_ ## FLAGS).AutoLogContext, LEVEL, WPP_BIT_ ## FLAGS + +#define WPP_LEVEL_FLAGS_ROS_ASSERT_EXP_POST(LEVEL, FLAGS, ROS_ASSERT_EXP) \ + ,((!(ROS_ASSERT_EXP)) ? _RosLogDebug(LEVEL) : 1) + + +#ifdef __cplusplus +} // extern "C" +#endif // __cplusplus + +#endif // _ROSLOGGING_H_ + diff --git a/render-only-sample/roscommon/Vc4Hw.h b/render-only-sample/roscommon/Vc4Hw.h index 5eb76b9..7963669 100644 --- a/render-only-sample/roscommon/Vc4Hw.h +++ b/render-only-sample/roscommon/Vc4Hw.h @@ -990,22 +990,52 @@ typedef enum _VC4TextureMinFilter const UINT VC4_BINNING_TILE_PIXELS = 64; // -// Constants related to tiled textures +// Structure and constants related to tiled textures // -const UINT VC4_1KB_SUB_TILE_WIDTH = 16; -const UINT VC4_1KB_SUB_TILE_HEIGHT = 16; -const UINT VC4_1KB_SUB_TILE_WIDTH_BYTES = 64; -const UINT VC4_1KB_SUB_TILE_SIZE_BYTES = 1024; +typedef struct _VC4TileInfo +{ + UINT VC4_4kBTileWidthPixels; + UINT VC4_4kBTileHeightPixels; + UINT VC4_4kBTileWidthBytes; + + UINT VC4_1kBSubTileWidthPixels; + UINT VC4_1kBSubTileHeightPixels; + UINT VC4_1kBSubTileWidthBytes; + + UINT VC4_MicroTileWidthBytes; + UINT vC4_MicroTileHeight; + +} VC4TileInfo; + +// General tiles, sub-tiles and micro-tiles information +const UINT VC4_MICRO_TILE_SIZE_BYTES = 64; +const UINT VC4_1KB_SUB_TILE_SIZE_BYTES = 1024; +const UINT VC4_4KB_TILE_SIZE_BYTES = 4096; + +// Precalculated values for 32 bpp tile +const UINT VC4_1KB_SUB_TILE_WIDTH_32BPP = 16; +const UINT VC4_1KB_SUB_TILE_HEIGHT_32BPP = 16; + +const UINT VC4_MICRO_TILE_WIDTH_32BPP = 4; +const UINT VC4_MICRO_TILE_HEIGHT_32BPP = 4; +const UINT VC4_MICRO_TILE_WIDTH_BYTES_32BPP = 16; + +// Precalculated values for 16 bpp tile +const UINT VC4_1KB_SUB_TILE_WIDTH_16BPP = 16; +const UINT VC4_1KB_SUB_TILE_HEIGHT_16BPP = 32; + +const UINT VC4_MICRO_TILE_WIDTH_16BPP = 4; +const UINT VC4_MICRO_TILE_HEIGHT_16BPP = 8; +const UINT VC4_MICRO_TILE_WIDTH_BYTES_16BPP = 8; -const UINT VC4_4KB_TILE_WIDTH = 32; -const UINT VC4_4KB_TILE_HEIGHT = 32; -const UINT VC4_4KB_TILE_WIDTH_BYTES = 128; -const UINT VC4_4KB_TILE_SIZE_BYTES = 4096; +// Precalculated values for 8 bpp tile +const UINT VC4_1KB_SUB_TILE_WIDTH_8BPP = 32; +const UINT VC4_1KB_SUB_TILE_HEIGHT_8BPP = 32; -const UINT VC4_MICRO_TILE_WIDTH_BYTES = 16; -const UINT VC4_MICRO_TILE_HEIGHT = 4; -const UINT VC4_MICRO_TILE_SIZE_BYTES = 64; +const UINT VC4_MICRO_TILE_WIDTH_8BPP = 8; +const UINT VC4_MICRO_TILE_HEIGHT_8BPP = 8; +const UINT VC4_MICRO_TILE_WIDTH_BYTES_8BPP = 8; // // VC4 bus address alias diff --git a/render-only-sample/roscompiler/DisasmBase.cpp b/render-only-sample/roscompiler/DisasmBase.cpp index c2c107d..94bbb89 100644 --- a/render-only-sample/roscompiler/DisasmBase.cpp +++ b/render-only-sample/roscompiler/DisasmBase.cpp @@ -1,4 +1,5 @@ -#include +#include "precomp.h" +#include "roscompiler.h" BaseDisasm::BaseDisasm() { diff --git a/render-only-sample/roscompiler/HLSLBinary.cpp b/render-only-sample/roscompiler/HLSLBinary.cpp index 900f9df..34ebb13 100644 --- a/render-only-sample/roscompiler/HLSLBinary.cpp +++ b/render-only-sample/roscompiler/HLSLBinary.cpp @@ -1,3 +1,4 @@ +#include "precomp.h" #include "roscompiler.h" BOOL IsOpCodeValid(D3D10_SB_OPCODE_TYPE OpCode) diff --git a/render-only-sample/roscompiler/HLSLBinary.hpp b/render-only-sample/roscompiler/HLSLBinary.hpp index 9b7bc6a..2f98ca4 100644 --- a/render-only-sample/roscompiler/HLSLBinary.hpp +++ b/render-only-sample/roscompiler/HLSLBinary.hpp @@ -49,6 +49,7 @@ UINT GetNumInstructionSrcOperands(D3D10_SB_OPCODE_TYPE OpCode); UINT GetNumInstructionDstOperands(D3D10_SB_OPCODE_TYPE OpCode); D3D11_SB_OPCODE_CLASS GetOpcodeClass(D3D10_SB_OPCODE_TYPE OpCode); TCHAR* GetOpcodeString(D3D10_SB_OPCODE_TYPE OpCode); +void InitInstructionInfo(); //***************************************************************************** // diff --git a/render-only-sample/roscompiler/HLSLDisasm.cpp b/render-only-sample/roscompiler/HLSLDisasm.cpp index c91136b..18823b6 100644 --- a/render-only-sample/roscompiler/HLSLDisasm.cpp +++ b/render-only-sample/roscompiler/HLSLDisasm.cpp @@ -1,3 +1,4 @@ +#include "precomp.h" #include "roscompiler.h" //---------------------------------------------------------------------------- diff --git a/render-only-sample/roscompiler/Vc4Disasm.cpp b/render-only-sample/roscompiler/Vc4Disasm.cpp index 529af49..311140b 100644 --- a/render-only-sample/roscompiler/Vc4Disasm.cpp +++ b/render-only-sample/roscompiler/Vc4Disasm.cpp @@ -1,3 +1,4 @@ +#include "precomp.h" #include "roscompiler.h" #if VC4 diff --git a/render-only-sample/roscompiler/Vc4Emit.cpp b/render-only-sample/roscompiler/Vc4Emit.cpp index 5308c77..e4e0d38 100644 --- a/render-only-sample/roscompiler/Vc4Emit.cpp +++ b/render-only-sample/roscompiler/Vc4Emit.cpp @@ -1,3 +1,4 @@ +#include "precomp.h" #include "roscompiler.h" #if VC4 diff --git a/render-only-sample/roscompiler/Vc4Emit.hpp b/render-only-sample/roscompiler/Vc4Emit.hpp index 06c7d14..836be2c 100644 --- a/render-only-sample/roscompiler/Vc4Emit.hpp +++ b/render-only-sample/roscompiler/Vc4Emit.hpp @@ -298,6 +298,11 @@ class Vc4Instruction Vc4_a_Inst(VC4_QPU_OPCODE_ADD_FTOI, dst, src, cond); } + void Vc4_a_IADD(Vc4Register dst, Vc4Register src1, Vc4Register src2, uint8_t cond = VC4_QPU_COND_ALWAYS) + { + Vc4_a_Inst(VC4_QPU_OPCODE_ADD_ADD, dst, src1, src2, cond); + } + void Vc4_a_MOV(Vc4Register dst, Vc4Register src, uint8_t cond = VC4_QPU_COND_ALWAYS) { Vc4_a_Inst(VC4_QPU_OPCODE_ADD_OR, dst, src, cond); diff --git a/render-only-sample/roscompiler/Vc4Shader.cpp b/render-only-sample/roscompiler/Vc4Shader.cpp index 6350091..5d7b737 100644 --- a/render-only-sample/roscompiler/Vc4Shader.cpp +++ b/render-only-sample/roscompiler/Vc4Shader.cpp @@ -1,3 +1,4 @@ +#include "precomp.h" #include "roscompiler.h" HRESULT Vc4ShaderStorage::Initialize() @@ -537,6 +538,9 @@ void Vc4Shader::Emit_with_Add_pipe(CInstruction &Inst) case D3D10_SB_OPCODE_MIN: Vc4Inst.Vc4_a_FMIN(_dst, src[0], src[1]); break; + case D3D10_SB_OPCODE_IADD: + Vc4Inst.Vc4_a_IADD(_dst, src[0], src[1]); + break; default: VC4_ASSERT(false); } @@ -649,11 +653,15 @@ void Vc4Shader::Emit_Sample(CInstruction &Inst) uint32_t texDimension = this->ResourceDimension[resourceIndex]; DXGI_FORMAT texFormat = UmdCompiler->GetShaderResourceFormat((uint8_t)resourceIndex); - VC4_ASSERT((texFormat == DXGI_FORMAT_B8G8R8A8_UNORM) || (texFormat == DXGI_FORMAT_R8G8B8A8_UNORM)); + VC4_ASSERT((texFormat == DXGI_FORMAT_B8G8R8A8_UNORM) + || (texFormat == DXGI_FORMAT_R8G8B8A8_UNORM) + || (texFormat == DXGI_FORMAT_R8G8_UNORM) + || (texFormat == DXGI_FORMAT_R8_UNORM) + || (texFormat == DXGI_FORMAT_A8_UNORM)); // TODO: more generic color channel swizzle support. - boolean bSwapColorChannel = (texFormat != DXGI_FORMAT_R8G8B8A8_UNORM); - + boolean bSwapColorChannel = (texFormat == DXGI_FORMAT_B8G8R8A8_UNORM); + // Texture coordinate VC4_ASSERT(Inst.m_Operands[1].m_NumComponents == D3D10_SB_OPERAND_4_COMPONENT); VC4_ASSERT(Inst.m_Operands[1].m_IndexDimension == D3D10_SB_OPERAND_INDEX_1D); @@ -834,11 +842,14 @@ void Vc4Shader::HLSL_ParseDecl() { case D3D10_SB_OPCODE_DCL_RESOURCE: HLSL_GetShaderInstruction(this->HLSLParser, Inst); - VC4_ASSERT(cResource < 8); - this->ResourceDimension[cResource++] = Inst.m_ResourceDecl.SRVInfo.Dimension; + VC4_ASSERT(Inst.m_Operands[0].m_Index[0].m_RegIndex < ARRAYSIZE(this->ResourceDimension)); + this->ResourceDimension[Inst.m_Operands[0].m_Index[0].m_RegIndex] = Inst.m_ResourceDecl.SRVInfo.Dimension; + cResources++; break; case D3D10_SB_OPCODE_DCL_CONSTANT_BUFFER: HLSL_GetShaderInstruction(this->HLSLParser, Inst); + // Issue 37: VC4 Find_Vc4Register_I needs to implement dynamic index support for constant buffers + VC4_ASSERT(Inst.m_ResourceDecl.CBInfo.AccessPattern == D3D10_SB_CONSTANT_BUFFER_IMMEDIATE_INDEXED); cConstants++; break; case D3D10_SB_OPCODE_DCL_SAMPLER: @@ -1035,6 +1046,7 @@ HRESULT Vc4Shader::Translate_VS() case D3D10_SB_OPCODE_ADD: case D3D10_SB_OPCODE_MAX: case D3D10_SB_OPCODE_MIN: + case D3D10_SB_OPCODE_IADD: this->Emit_with_Add_pipe(Inst); break; case D3D10_SB_OPCODE_DP2: diff --git a/render-only-sample/roscompiler/Vc4Shader.hpp b/render-only-sample/roscompiler/Vc4Shader.hpp index f3e34f0..0b896a1 100644 --- a/render-only-sample/roscompiler/Vc4Shader.hpp +++ b/render-only-sample/roscompiler/Vc4Shader.hpp @@ -206,7 +206,7 @@ class Vc4Shader cTemp(0), cSampler(0), cConstants(0), - cResource(0) + cResources(0) { memset(this->InputRegister, 0, sizeof(this->InputRegister)); memset(this->OutputRegister, 0, sizeof(this->OutputRegister)); @@ -399,8 +399,7 @@ class Vc4Shader case D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER: VC4_ASSERT(c.m_NumComponents == D3D10_SB_OPERAND_4_COMPONENT); VC4_ASSERT(c.m_IndexDimension == D3D10_SB_OPERAND_INDEX_2D); - VC4_ASSERT(c.m_IndexType[0] == D3D10_SB_OPERAND_INDEX_IMMEDIATE32); - VC4_ASSERT(c.m_IndexType[1] == D3D10_SB_OPERAND_INDEX_IMMEDIATE32); + VC4_ASSERT(c.m_IndexType[0] == D3D10_SB_OPERAND_INDEX_IMMEDIATE32); // constant buffer slot { Vc4Register unif(VC4_QPU_ALU_REG_A, VC4_QPU_RADDR_UNIFORM); // TODO: fix hardcoded REG_A. @@ -412,16 +411,28 @@ class Vc4Shader u.Type = VC4_UNIFORM_TYPE_USER_CONSTANT; u.userConstant.bufferSlot = c.m_Index[0].m_RegIndex; - switch (c.m_ComponentSelection) + switch (c.m_IndexType[1]) { - case D3D10_SB_OPERAND_4_COMPONENT_SWIZZLE_MODE: - u.userConstant.bufferOffset = (c.m_Index[1].m_RegIndex * 4) + c.m_Swizzle[swizzleIndex]; + case D3D10_SB_OPERAND_INDEX_IMMEDIATE32: + switch (c.m_ComponentSelection) + { + case D3D10_SB_OPERAND_4_COMPONENT_SWIZZLE_MODE: + u.userConstant.bufferOffset = (c.m_Index[1].m_RegIndex * 4) + c.m_Swizzle[swizzleIndex]; + break; + case D3D10_SB_OPERAND_4_COMPONENT_SELECT_1_MODE: + u.userConstant.bufferOffset = (c.m_Index[1].m_RegIndex * 4) + c.m_ComponentName; + break; + default: + VC4_ASSERT(false); + } break; - case D3D10_SB_OPERAND_4_COMPONENT_SELECT_1_MODE: - u.userConstant.bufferOffset = (c.m_Index[1].m_RegIndex * 4) + c.m_ComponentName; + case D3D10_SB_OPERAND_INDEX_RELATIVE: + // Issue 37: VC4 Find_Vc4Register_I needs to implement dynamic index support for constant buffers + VC4_ASSERT(false); break; default: VC4_ASSERT(false); + break; } this->AddUniformReference(u); @@ -675,6 +686,7 @@ class Vc4Shader uint8_t cSampler; uint8_t cConstants; + uint8_t cResources; // Register map uint8_t cInput; @@ -686,8 +698,7 @@ class Vc4Shader uint8_t cTemp; Vc4Register TempRegister[4][4]; - uint8_t cResource; - uint32_t ResourceDimension[8]; + uint32_t ResourceDimension[16]; // TEMPORARY Register Usage Map // diff --git a/render-only-sample/roscompiler/precomp.cpp b/render-only-sample/roscompiler/precomp.cpp new file mode 100644 index 0000000..ceeb0d6 --- /dev/null +++ b/render-only-sample/roscompiler/precomp.cpp @@ -0,0 +1 @@ +#include "precomp.h" diff --git a/render-only-sample/roscompiler/precomp.h b/render-only-sample/roscompiler/precomp.h new file mode 100644 index 0000000..9c54b1e --- /dev/null +++ b/render-only-sample/roscompiler/precomp.h @@ -0,0 +1,7 @@ +#ifndef _ROSCOMPILER_PRECOMP_H_ +#define _ROSCOMPILER_PRECOMP_H_ + +#include +#include "d3dumddi_.h" + +#endif // _ROSCOMPILER_PRECOMP_H_ diff --git a/render-only-sample/roscompiler/roscompiler.cpp b/render-only-sample/roscompiler/roscompiler.cpp index 0a76426..c2710a1 100644 --- a/render-only-sample/roscompiler/roscompiler.cpp +++ b/render-only-sample/roscompiler/roscompiler.cpp @@ -1,9 +1,7 @@ +#include "precomp.h" #include "roscompiler.h" -void __stdcall InitInstructionInfo(); -void __stdcall VC4_InitializeName(); - -void __stdcall InitializeShaderCompilerLibrary() +void InitializeShaderCompilerLibrary() { InitInstructionInfo(); } diff --git a/render-only-sample/roscompiler/roscompiler.h b/render-only-sample/roscompiler/roscompiler.h index 9b7ef7e..e5775ab 100644 --- a/render-only-sample/roscompiler/roscompiler.h +++ b/render-only-sample/roscompiler/roscompiler.h @@ -1,7 +1,5 @@ #pragma once -#include "d3dumddi_.h" - #include "roscompilerdebug.h" #include "DisasmBase.hpp" #include "HLSLBinary.hpp" @@ -36,6 +34,8 @@ class RosUmdDevice; #define ROS_PIXEL_SHADER_STORAGE 0 #define ROS_PIXEL_SHADER_UNIFORM_STORAGE 1 +void InitializeShaderCompilerLibrary(); + class RosCompiler { public: diff --git a/render-only-sample/roscompiler/roscompiler.vcxproj b/render-only-sample/roscompiler/roscompiler.vcxproj index 28cbc48..173abda 100644 --- a/render-only-sample/roscompiler/roscompiler.vcxproj +++ b/render-only-sample/roscompiler/roscompiler.vcxproj @@ -34,101 +34,26 @@ ARM64 - - - - - - - - - - - - - - - - - - - - - {98E16C06-7E74-4A0C-A5E6-24219CAE527D} {0a049372-4c4d-4ea0-a64e-dc6ad88ceca1} - v4.5.2 - 12.0 - Debug - Win32 roscompiler $(LatestTargetPlatformVersion) - + Windows10 - true - WindowsUserModeDriver10.0 - StaticLibrary - Universal - Unicode - - - Windows10 - false WindowsUserModeDriver10.0 StaticLibrary Universal - Unicode - - Windows10 - true - WindowsUserModeDriver10.0 - StaticLibrary - Universal - Unicode - - - Windows10 - false - WindowsUserModeDriver10.0 - StaticLibrary - Universal - Unicode - - - Windows10 + + true - WindowsUserModeDriver10.0 - StaticLibrary - Universal - Unicode - - - Windows10 - false - WindowsUserModeDriver10.0 - StaticLibrary - Universal - Unicode - - - Windows10 - true - WindowsUserModeDriver10.0 - StaticLibrary - Universal - Unicode - - Windows10 + + false - WindowsUserModeDriver10.0 - StaticLibrary - Universal - Unicode @@ -137,78 +62,66 @@ - - $(IncludePath);$(KM_IncludePath);$(SolutionDir)\roscommon - - - $(IncludePath);$(KM_IncludePath);$(SolutionDir)\roscommon - - - $(IncludePath);$(KM_IncludePath);$(SolutionDir)\roscommon - - - $(IncludePath);$(KM_IncludePath);$(SolutionDir)\roscommon - - - $(IncludePath);$(KM_IncludePath);$(SolutionDir)\roscommon - - - $(IncludePath);$(KM_IncludePath);$(SolutionDir)\roscommon - - - $(IncludePath);$(KM_IncludePath);$(SolutionDir)\roscommon - - - $(IncludePath);$(KM_IncludePath);$(SolutionDir)\roscommon - - - - VC4=1;%(PreprocessorDefinitions) - Sync - - - - - VC4=1;%(PreprocessorDefinitions) - Sync - - - + + - VC4=1;%(PreprocessorDefinitions) + Use + precomp.h + Level4 + true + + true Sync + 4201 + VC4=1;_USE_DECLSPECS_FOR_SAL=1;%(PreprocessorDefinitions) + ..\roscommon;..\rosumd;$(KM_IncludePath);%(AdditionalIncludeDirectories) - + + - VC4=1;%(PreprocessorDefinitions) - Sync + false + true + + false + - + + - VC4=1;%(PreprocessorDefinitions) - Sync + true + true + + true + - - - VC4=1;%(PreprocessorDefinitions) - Sync - - - - - VC4=1;%(PreprocessorDefinitions) - Sync - - - - - VC4=1;%(PreprocessorDefinitions) - Sync + + + + + + + + + + + + + + + + Create - + + + + + + + + diff --git a/render-only-sample/rosdriver/Ros.inf b/render-only-sample/rosdriver/Ros.inf index c4fb2fd..f981b2a 100644 --- a/render-only-sample/rosdriver/Ros.inf +++ b/render-only-sample/rosdriver/Ros.inf @@ -53,6 +53,9 @@ rosumd.dll,,,0x4000 [RenderOnlySample_AddReg] HKR,,UserModeDriverName,%REG_MULTI_SZ%,rosumd.dll,rosumd.dll,rosumd.dll,rosumd.dll +HKLM,"SYSTEM\CurrentControlSet\Control\GraphicsDrivers\Scheduler",EnablePreemption,%REG_DWORD%,0 +HKLM,"SYSTEM\CurrentControlSet\Control\GraphicsDrivers",TdrDebugMode,%REG_DWORD%,1 +HKLM,"SYSTEM\CurrentControlSet\Control\GraphicsDrivers\MemoryManager",DirectFlipMemoryRequirement,%REG_DWORD%,0 ; Service Installation diff --git a/render-only-sample/roskmd/RosKmd.vcxproj b/render-only-sample/roskmd/RosKmd.vcxproj index be7109e..5f16e4e 100644 --- a/render-only-sample/roskmd/RosKmd.vcxproj +++ b/render-only-sample/roskmd/RosKmd.vcxproj @@ -146,7 +146,7 @@ precomp.h true true - RosKmdLogging.h + ..\roscommon\RosLogging.h true ROSKMD ENABLE_WPP_RECORDER=1;WPP_EMIT_FUNC_NAME diff --git a/render-only-sample/roskmd/RosKmd.vcxproj.filters b/render-only-sample/roskmd/RosKmd.vcxproj.filters index 0fc10fb..5368b34 100644 --- a/render-only-sample/roskmd/RosKmd.vcxproj.filters +++ b/render-only-sample/roskmd/RosKmd.vcxproj.filters @@ -31,8 +31,18 @@ Source Files - - + + Source Files + + + Source Files + + + Source Files + + + Source Files + @@ -86,7 +96,21 @@ Header Files - + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + diff --git a/render-only-sample/roskmd/RosKmdAdapter.cpp b/render-only-sample/roskmd/RosKmdAdapter.cpp index 8923ea2..9d06127 100644 --- a/render-only-sample/roskmd/RosKmdAdapter.cpp +++ b/render-only-sample/roskmd/RosKmdAdapter.cpp @@ -1,2189 +1,2193 @@ - -#include "precomp.h" - -#include "RosKmdLogging.h" -#include "RosKmdAdapter.tmh" - -#include "RosKmd.h" -#include "RosKmdAdapter.h" -#include "RosKmdRapAdapter.h" -#include "RosKmdSoftAdapter.h" -#include "RosKmdAllocation.h" -#include "RosKmdContext.h" -#include "RosKmdResource.h" -#include "RosKmdGlobal.h" -#include "RosKmdUtil.h" -#include "RosGpuCommand.h" -#include "RosKmdAcpi.h" -#include "RosKmdUtil.h" -#include "Vc4Hw.h" -#include "Vc4Ddi.h" -#include "Vc4Mailbox.h" - -void * RosKmAdapter::operator new(size_t size) -{ - return ExAllocatePoolWithTag(NonPagedPoolNx, size, 'ROSD'); -} - -void RosKmAdapter::operator delete(void * ptr) -{ - ExFreePool(ptr); -} - -RosKmAdapter::RosKmAdapter(IN_CONST_PDEVICE_OBJECT PhysicalDeviceObject, OUT_PPVOID MiniportDeviceContext) : - m_display(PhysicalDeviceObject, m_DxgkInterface, m_DxgkStartInfo, m_deviceInfo) -{ - m_magic = kMagic; - m_pPhysicalDevice = PhysicalDeviceObject; - - // Enable in RosKmAdapter::Start() when device is ready for interrupt - m_bReadyToHandleInterrupt = FALSE; - - // Set initial power management state. - m_PowerManagementStarted = FALSE; - m_AdapterPowerDState = PowerDeviceD0; // Device is at D0 at startup - m_NumPowerComponents = 0; - RtlZeroMemory(&m_EnginePowerFState[0], sizeof(m_EnginePowerFState)); // Components are F0 at startup. - - RtlZeroMemory(&m_deviceId, sizeof(m_deviceId)); - m_deviceIdLength = 0; - - m_flags.m_value = 0; - -#if VC4 - -#if GPU_CACHE_WORKAROUND - - m_rtSizeJitter = 0; - -#endif - - m_busAddressOffset = 0; - -#endif - - *MiniportDeviceContext = this; -} - -RosKmAdapter::~RosKmAdapter() -{ - // do nothing -} - -NTSTATUS -RosKmAdapter::AddAdapter( - IN_CONST_PDEVICE_OBJECT PhysicalDeviceObject, - OUT_PPVOID MiniportDeviceContext) -{ - NTSTATUS status; - WCHAR deviceID[512]; - ULONG dataLen; - - status = IoGetDeviceProperty(PhysicalDeviceObject, DevicePropertyHardwareID, sizeof(deviceID), deviceID, &dataLen); - if (!NT_SUCCESS(status)) - { - ROS_LOG_ERROR( - "Failed to get DevicePropertyHardwareID from PDO. (status=%!STATUS!)", - status); - return status; - } - - RosKmAdapter *pRosKmAdapter = nullptr; - if (wcscmp(deviceID, L"ACPI\\VEN_BCM&DEV_2850") == 0) - { - pRosKmAdapter = new RosKmdRapAdapter(PhysicalDeviceObject, MiniportDeviceContext); - if (!pRosKmAdapter) { - ROS_LOG_LOW_MEMORY("Failed to allocate RosKmdRapAdapter."); - return STATUS_NO_MEMORY; - } - } - else - { - pRosKmAdapter = new RosKmdSoftAdapter(PhysicalDeviceObject, MiniportDeviceContext); - if (!pRosKmAdapter) { - ROS_LOG_LOW_MEMORY("Failed to allocate RosKmdSoftAdapter."); - return STATUS_NO_MEMORY; - } - } - - return STATUS_SUCCESS; -} - -NTSTATUS -RosKmAdapter::QueryEngineStatus( - DXGKARG_QUERYENGINESTATUS *pQueryEngineStatus) -{ - ROS_LOG_TRACE("QueryEngineStatus was called."); - - pQueryEngineStatus->EngineStatus.Responsive = 1; - return STATUS_SUCCESS; -} - -void RosKmAdapter::WorkerThread(void * inThis) -{ - RosKmAdapter *pRosKmAdapter = RosKmAdapter::Cast(inThis); - - pRosKmAdapter->DoWork(); -} - -void RosKmAdapter::DoWork(void) -{ - bool done = false; - - while (!done) - { - NTSTATUS status = KeWaitForSingleObject( - &m_workerThreadEvent, - Executive, - KernelMode, - FALSE, - NULL); - - status; - NT_ASSERT(status == STATUS_SUCCESS); - - if (m_workerExit) - { - done = true; - continue; - } - - for (;;) - { - ROSDMABUFSUBMISSION * pDmaBufSubmission = DequeueDmaBuffer(&m_dmaBufQueueLock); - if (pDmaBufSubmission == NULL) - { - break; - } - - ROSDMABUFINFO * pDmaBufInfo = pDmaBufSubmission->m_pDmaBufInfo; - - if (pDmaBufInfo->m_DmaBufState.m_bPaging) - { - // - // Run paging buffer in software - // - - ProcessPagingBuffer(pDmaBufSubmission); - - NotifyDmaBufCompletion(pDmaBufSubmission); - } - else - { - // - // Process render DMA buffer - // - - ProcessRenderBuffer(pDmaBufSubmission); - - NotifyDmaBufCompletion(pDmaBufSubmission); - } - - ExInterlockedInsertTailList(&m_dmaBufSubmissionFree, &pDmaBufSubmission->m_QueueEntry, &m_dmaBufQueueLock); - } - } -} - -ROSDMABUFSUBMISSION * -RosKmAdapter::DequeueDmaBuffer( - KSPIN_LOCK *pDmaBufQueueLock) -{ - LIST_ENTRY *pDmaEntry; - - if (pDmaBufQueueLock) - { - pDmaEntry = ExInterlockedRemoveHeadList(&m_dmaBufQueue, pDmaBufQueueLock); - } - else - { - if (!IsListEmpty(&m_dmaBufQueue)) - { - pDmaEntry = RemoveHeadList(&m_dmaBufQueue); - } - else - { - pDmaEntry = NULL; - } - } - - return CONTAINING_RECORD(pDmaEntry, ROSDMABUFSUBMISSION, m_QueueEntry); -} - -void -RosKmAdapter::ProcessPagingBuffer( - ROSDMABUFSUBMISSION * pDmaBufSubmission) -{ - ROSDMABUFINFO * pDmaBufInfo = pDmaBufSubmission->m_pDmaBufInfo; - - NT_ASSERT(0 == (pDmaBufSubmission->m_EndOffset - pDmaBufSubmission->m_StartOffset) % sizeof(DXGKARG_BUILDPAGINGBUFFER)); - - DXGKARG_BUILDPAGINGBUFFER * pPagingBuffer = (DXGKARG_BUILDPAGINGBUFFER *)(pDmaBufInfo->m_pDmaBuffer + pDmaBufSubmission->m_StartOffset); - DXGKARG_BUILDPAGINGBUFFER * pEndofBuffer = (DXGKARG_BUILDPAGINGBUFFER *)(pDmaBufInfo->m_pDmaBuffer + pDmaBufSubmission->m_EndOffset); - - for (; pPagingBuffer < pEndofBuffer; pPagingBuffer++) - { - switch (pPagingBuffer->Operation) - { - case DXGK_OPERATION_FILL: - { - NT_ASSERT(pPagingBuffer->Fill.Destination.SegmentId == ROSD_SEGMENT_VIDEO_MEMORY); - NT_ASSERT(pPagingBuffer->Fill.FillSize % sizeof(ULONG) == 0); - - ULONG * const startAddress = reinterpret_cast( - (BYTE *)RosKmdGlobal::s_pVideoMemory + - pPagingBuffer->Fill.Destination.SegmentAddress.QuadPart); - for (ULONG * ptr = startAddress; - ptr != (startAddress + pPagingBuffer->Fill.FillSize / sizeof(ULONG)); - ++ptr) - { - *ptr = pPagingBuffer->Fill.FillPattern; - } - } - break; - case DXGK_OPERATION_TRANSFER: - { - PBYTE pSource, pDestination; - MDL * pMdlToRestore = NULL; - CSHORT savedMdlFlags = 0; - PBYTE pKmAddrToUnmap = NULL; - - if (pPagingBuffer->Transfer.Source.SegmentId == ROSD_SEGMENT_VIDEO_MEMORY) - { - pSource = ((BYTE *)RosKmdGlobal::s_pVideoMemory) + pPagingBuffer->Transfer.Source.SegmentAddress.QuadPart; - } - else - { - NT_ASSERT(pPagingBuffer->Transfer.Source.SegmentId == 0); - - pMdlToRestore = pPagingBuffer->Transfer.Source.pMdl; - savedMdlFlags = pMdlToRestore->MdlFlags; - - pSource = (PBYTE)MmGetSystemAddressForMdlSafe(pPagingBuffer->Transfer.Source.pMdl, HighPagePriority); - - pKmAddrToUnmap = pSource; - - // Adjust the source address by MdlOffset - pSource += (pPagingBuffer->Transfer.MdlOffset*PAGE_SIZE); - } - - if (pPagingBuffer->Transfer.Destination.SegmentId == ROSD_SEGMENT_VIDEO_MEMORY) - { - pDestination = ((BYTE *)RosKmdGlobal::s_pVideoMemory) + pPagingBuffer->Transfer.Destination.SegmentAddress.QuadPart; - } - else - { - NT_ASSERT(pPagingBuffer->Transfer.Destination.SegmentId == 0); - - pMdlToRestore = pPagingBuffer->Transfer.Destination.pMdl; - savedMdlFlags = pMdlToRestore->MdlFlags; - - pDestination = (PBYTE)MmGetSystemAddressForMdlSafe(pPagingBuffer->Transfer.Destination.pMdl, HighPagePriority); - - pKmAddrToUnmap = pDestination; - - // Adjust the destination address by MdlOffset - pDestination += (pPagingBuffer->Transfer.MdlOffset*PAGE_SIZE); - } - - if (pSource && pDestination) - { - RtlCopyMemory(pDestination, pSource, pPagingBuffer->Transfer.TransferSize); - } - else - { - // TODO[indyz]: Propagate the error back to runtime - m_ErrorHit.m_PagingFailure = 1; - } - - // Restore the state of the Mdl (for source or destionation) - if ((0 == (savedMdlFlags & MDL_MAPPED_TO_SYSTEM_VA)) && pKmAddrToUnmap) - { - MmUnmapLockedPages(pKmAddrToUnmap, pMdlToRestore); - } - } - break; - - default: - NT_ASSERT(false); - } - } -} - -void -RosKmAdapter::NotifyDmaBufCompletion( - ROSDMABUFSUBMISSION * pDmaBufSubmission) -{ - ROSDMABUFINFO * pDmaBufInfo = pDmaBufSubmission->m_pDmaBufInfo; - - if (! pDmaBufInfo->m_DmaBufState.m_bPaging) - { - pDmaBufInfo->m_DmaBufState.m_bCompleted = 1; - } - - // - // Notify the VidSch of the completion of the DMA buffer - // - NTSTATUS Status; - - RtlZeroMemory(&m_interruptData, sizeof(m_interruptData)); - - m_interruptData.InterruptType = DXGK_INTERRUPT_DMA_COMPLETED; - m_interruptData.DmaCompleted.SubmissionFenceId = pDmaBufSubmission->m_SubmissionFenceId; - m_interruptData.DmaCompleted.NodeOrdinal = 0; - m_interruptData.DmaCompleted.EngineOrdinal = 0; - - BOOLEAN bRet; - - Status = m_DxgkInterface.DxgkCbSynchronizeExecution( - m_DxgkInterface.DeviceHandle, - SynchronizeNotifyInterrupt, - this, - 0, - &bRet); - - if (!NT_SUCCESS(Status)) - { - m_ErrorHit.m_NotifyDmaBufCompletion = 1; - } -} - -BOOLEAN RosKmAdapter::SynchronizeNotifyInterrupt(PVOID inThis) -{ - RosKmAdapter *pRosKmAdapter = RosKmAdapter::Cast(inThis); - - return pRosKmAdapter->SynchronizeNotifyInterrupt(); -} - -BOOLEAN RosKmAdapter::SynchronizeNotifyInterrupt(void) -{ - m_DxgkInterface.DxgkCbNotifyInterrupt(m_DxgkInterface.DeviceHandle, &m_interruptData); - - return m_DxgkInterface.DxgkCbQueueDpc(m_DxgkInterface.DeviceHandle); -} - -NTSTATUS -RosKmAdapter::Start( - IN_PDXGK_START_INFO DxgkStartInfo, - IN_PDXGKRNL_INTERFACE DxgkInterface, - OUT_PULONG NumberOfVideoPresentSources, - OUT_PULONG NumberOfChildren) -{ - m_DxgkStartInfo = *DxgkStartInfo; - m_DxgkInterface = *DxgkInterface; - - // - // Render only device has no VidPn source and target - // Subclass should overwrite these values if it is not render-only. - // - *NumberOfVideoPresentSources = 0; - *NumberOfChildren = 0; - - // - // Sample for 1.3 model currently - // - m_WDDMVersion = DXGKDDI_WDDMv1_3; - - m_NumNodes = C_ROSD_GPU_ENGINE_COUNT; - - // - // Initialize worker - // - - KeInitializeEvent(&m_workerThreadEvent, SynchronizationEvent, FALSE); - - m_workerExit = false; - - OBJECT_ATTRIBUTES ObjectAttributes; - HANDLE hWorkerThread; - - InitializeObjectAttributes(&ObjectAttributes, NULL, OBJ_KERNEL_HANDLE, NULL, NULL); - - NTSTATUS status = PsCreateSystemThread( - &hWorkerThread, - THREAD_ALL_ACCESS, - &ObjectAttributes, - NULL, - NULL, - (PKSTART_ROUTINE) RosKmAdapter::WorkerThread, - this); - - if (status != STATUS_SUCCESS) - { - ROS_LOG_ERROR( - "PsCreateSystemThread(...) failed for RosKmAdapter::WorkerThread. (status=%!STATUS!)", - status); - return status; - } - - status = ObReferenceObjectByHandle( - hWorkerThread, - THREAD_ALL_ACCESS, - *PsThreadType, - KernelMode, - (PVOID *)&m_pWorkerThread, - NULL); - - ZwClose(hWorkerThread); - - if (!NT_SUCCESS(status)) - { - ROS_LOG_ERROR( - "ObReferenceObjectByHandle(...) failed for worker thread. (status=%!STATUS!)", - status); - return status; - } - - status = m_DxgkInterface.DxgkCbGetDeviceInformation( - m_DxgkInterface.DeviceHandle, - &m_deviceInfo); - if (!NT_SUCCESS(status)) - { - ROS_LOG_ERROR( - "DxgkCbGetDeviceInformation(...) failed. (status=%!STATUS!, m_DxgkInterface.DeviceHandle=0x%p)", - status, - m_DxgkInterface.DeviceHandle); - return status; - } - - // - // Query APCI device ID - // - { - NTSTATUS acpiStatus; - - RosKmAcpiReader acpiReader(this, DISPLAY_ADAPTER_HW_ID); - acpiStatus = acpiReader.Read(ACPI_METHOD_HARDWARE_ID); - if (NT_SUCCESS(acpiStatus) && (acpiReader.GetOutputArgumentCount() == 1)) - { - RosKmAcpiArgumentParser acpiParser(&acpiReader, NULL); - char *pDeviceId; - ULONG DeviceIdLength; - acpiStatus = acpiParser.GetAnsiString(&pDeviceId, &DeviceIdLength); - if (NT_SUCCESS(acpiStatus) && DeviceIdLength) - { - m_deviceIdLength = min(DeviceIdLength, sizeof(m_deviceId)); - RtlCopyMemory(&m_deviceId[0], pDeviceId, m_deviceIdLength); - } - } - } - - // - // Initialize power component data. - // - InitializePowerComponentInfo(); - - // - // Initialize apperture state - // - - memset(m_aperturePageTable, 0, sizeof(m_aperturePageTable)); - - // - // Intialize DMA buffer queue and lock - // - - InitializeListHead(&m_dmaBufSubmissionFree); - for (UINT i = 0; i < m_maxDmaBufQueueLength; i++) - { - InsertHeadList(&m_dmaBufSubmissionFree, &m_dmaBufSubssions[i].m_QueueEntry); - } - - InitializeListHead(&m_dmaBufQueue); - KeInitializeSpinLock(&m_dmaBufQueueLock); - - // - // Initialize HW DMA buffer compeletion DPC and event - // - - KeInitializeEvent(&m_hwDmaBufCompletionEvent, SynchronizationEvent, FALSE); - KeInitializeDpc(&m_hwDmaBufCompletionDpc, HwDmaBufCompletionDpcRoutine, this); - - ROS_LOG_TRACE("Adapter was successfully started."); - return STATUS_SUCCESS; -} - -NTSTATUS -RosKmAdapter::Stop() -{ - m_workerExit = true; - - KeSetEvent(&m_workerThreadEvent, 0, FALSE); - - NTSTATUS status = KeWaitForSingleObject( - m_pWorkerThread, - Executive, - KernelMode, - FALSE, - NULL); - - status; - NT_ASSERT(status == STATUS_SUCCESS); - - ObDereferenceObject(m_pWorkerThread); - - ROS_LOG_TRACE("Adapter was successfully stopped."); - return STATUS_SUCCESS; -} - -void RosKmAdapter::DpcRoutine(void) -{ - // dp nothing other than calling back into dxgk - - m_DxgkInterface.DxgkCbNotifyDpc(m_DxgkInterface.DeviceHandle); -} - -NTSTATUS -RosKmAdapter::BuildPagingBuffer( - IN_PDXGKARG_BUILDPAGINGBUFFER pArgs) -{ - NTSTATUS Status = STATUS_SUCCESS; - PBYTE pDmaBufStart = (PBYTE)pArgs->pDmaBuffer; - PBYTE pDmaBufPos = (PBYTE)pArgs->pDmaBuffer; - - // - // hAllocation is NULL for operation on DMA buffer and pages mapped into aperture - // - - // - // If there is insufficient space left in DMA buffer, we should return - // STATUS_GRAPHICS_INSUFFICIENT_DMA_BUFFER. - // - - switch (pArgs->Operation) - { - case DXGK_OPERATION_MAP_APERTURE_SEGMENT: - { - if (pArgs->MapApertureSegment.SegmentId == kApertureSegmentId) - { - size_t pageIndex = pArgs->MapApertureSegment.OffsetInPages; - size_t pageCount = pArgs->MapApertureSegment.NumberOfPages; - - NT_ASSERT(pageIndex + pageCount <= kApertureSegmentPageCount); - - size_t mdlPageOffset = pArgs->MapApertureSegment.MdlOffset; - - PMDL pMdl = pArgs->MapApertureSegment.pMdl; - - for (UINT i = 0; i < pageCount; i++) - { - m_aperturePageTable[pageIndex + i] = MmGetMdlPfnArray(pMdl)[mdlPageOffset + i]; - } - } - - } - break; - - case DXGK_OPERATION_UNMAP_APERTURE_SEGMENT: - { - if (pArgs->MapApertureSegment.SegmentId == kApertureSegmentId) - { - size_t pageIndex = pArgs->MapApertureSegment.OffsetInPages; - size_t pageCount = pArgs->MapApertureSegment.NumberOfPages; - - NT_ASSERT(pageIndex + pageCount <= kApertureSegmentPageCount); - - while (pageCount--) - { - m_aperturePageTable[pageIndex++] = 0; - } - } - } - - break; - - case DXGK_OPERATION_FILL: - { - RosKmdAllocation * pRosKmdAllocation = (RosKmdAllocation *)pArgs->Fill.hAllocation; - pRosKmdAllocation; - - ROS_LOG_TRACE( - "Filling DMA buffer. (Destination.SegmentAddress=0x%I64x, FillPattern=0x%lx, FillSize=%Id)", - pArgs->Fill.Destination.SegmentAddress.QuadPart, - pArgs->Fill.FillPattern, - pArgs->Fill.FillSize); - - if (pArgs->DmaSize < sizeof(DXGKARG_BUILDPAGINGBUFFER)) - { - ROS_LOG_ERROR( - "DXGK_OPERATION_FILL: DMA buffer size is too small. (pArgs->DmaSize=%d, sizeof(DXGKARG_BUILDPAGINGBUFFER)=%d)", - pArgs->DmaSize, - sizeof(DXGKARG_BUILDPAGINGBUFFER)); - return STATUS_GRAPHICS_INSUFFICIENT_DMA_BUFFER; - } - else - { - *((DXGKARG_BUILDPAGINGBUFFER *)pArgs->pDmaBuffer) = *pArgs; - - pDmaBufPos += sizeof(DXGKARG_BUILDPAGINGBUFFER); - } - } - break; - - case DXGK_OPERATION_DISCARD_CONTENT: - { - // do nothing - } - break; - - case DXGK_OPERATION_TRANSFER: - { - if (pArgs->DmaSize < sizeof(DXGKARG_BUILDPAGINGBUFFER)) - { - ROS_LOG_ERROR( - "DXGK_OPERATION_TRANSFER: DMA buffer is too small. (pArgs->DmaSize=%d, sizeof(DXGKARG_BUILDPAGINGBUFFER)=%d)", - pArgs->DmaSize, - sizeof(DXGKARG_BUILDPAGINGBUFFER)); - return STATUS_GRAPHICS_INSUFFICIENT_DMA_BUFFER; - } - else - { - *((DXGKARG_BUILDPAGINGBUFFER *)pArgs->pDmaBuffer) = *pArgs; - - pDmaBufPos += sizeof(DXGKARG_BUILDPAGINGBUFFER); - } - } - break; - - default: - { - NT_ASSERT(false); - - m_ErrorHit.m_UnSupportedPagingOp = 1; - Status = STATUS_SUCCESS; - } - break; - } - - // - // Update pDmaBuffer to point past the last byte used. - pArgs->pDmaBuffer = pDmaBufPos; - - // Record DMA buffer information only when it is newly used - ROSDMABUFINFO * pDmaBufInfo = (ROSDMABUFINFO *)pArgs->pDmaBufferPrivateData; - if (pDmaBufInfo && (pArgs->DmaSize == ROSD_PAGING_BUFFER_SIZE)) - { - pDmaBufInfo->m_DmaBufState.m_Value = 0; - pDmaBufInfo->m_DmaBufState.m_bPaging = 1; - - pDmaBufInfo->m_pDmaBuffer = pDmaBufStart; - pDmaBufInfo->m_DmaBufferSize = pArgs->DmaSize; - } - - return Status; -} - -NTSTATUS -RosKmAdapter::DispatchIoRequest( - IN_ULONG VidPnSourceId, - IN_PVIDEO_REQUEST_PACKET VideoRequestPacket) -{ - if (RosKmdGlobal::IsRenderOnly()) - { - ROS_LOG_WARNING( - "Unsupported IO Control Code. (VideoRequestPacketPtr->IoControlCode = 0x%lx)", - VideoRequestPacket->IoControlCode); - return STATUS_NOT_SUPPORTED; - } - - return m_display.DispatchIoRequest(VidPnSourceId, VideoRequestPacket); -} - -NTSTATUS -RosKmAdapter::SubmitCommand( - IN_CONST_PDXGKARG_SUBMITCOMMAND pSubmitCommand) -{ - NTSTATUS Status = STATUS_SUCCESS; - -#if VC4 - - if (!pSubmitCommand->Flags.Paging) - { - // - // Patch DMA buffer self-reference - // - ROSDMABUFINFO *pDmaBufInfo = (ROSDMABUFINFO *)pSubmitCommand->pDmaBufferPrivateData; - BYTE *pDmaBuf = pDmaBufInfo->m_pDmaBuffer; - UINT dmaBufPhysicalAddress; - - // - // Need to record DMA buffer physical address for fully pre-patched DMA buffer - // - pDmaBufInfo->m_DmaBufferPhysicalAddress = pSubmitCommand->DmaBufferPhysicalAddress; - - dmaBufPhysicalAddress = GetAperturePhysicalAddress( - pSubmitCommand->DmaBufferPhysicalAddress.LowPart); - - for (UINT i = 0; i < pDmaBufInfo->m_DmaBufState.m_NumDmaBufSelfRef; i++) - { - D3DDDI_PATCHLOCATIONLIST *pPatchLoc = &pDmaBufInfo->m_DmaBufSelfRef[i]; - - *((UINT *)(pDmaBuf + pPatchLoc->PatchOffset)) = - dmaBufPhysicalAddress + - m_busAddressOffset + - pPatchLoc->AllocationOffset; - } - } - -#endif - - // NOTE: pRosKmContext will be NULL for paging operations - RosKmContext *pRosKmContext = (RosKmContext *)pSubmitCommand->hContext; - pRosKmContext; - - QueueDmaBuffer(pSubmitCommand); - - // - // Wake up the worker thread for the GPU node - // - KeSetEvent(&m_workerThreadEvent, 0, FALSE); - - return Status; -} - -NTSTATUS -RosKmAdapter::Patch( - IN_CONST_PDXGKARG_PATCH pPatch) -{ - ROSDMABUFINFO *pDmaBufInfo = (ROSDMABUFINFO *)pPatch->pDmaBufferPrivateData; - - RosKmContext * pRosKmContext = (RosKmContext *)pPatch->hContext; - pRosKmContext; - - pDmaBufInfo->m_DmaBufferPhysicalAddress = pPatch->DmaBufferPhysicalAddress; - - PatchDmaBuffer( - pDmaBufInfo, - pPatch->pAllocationList, - pPatch->AllocationListSize, - pPatch->pPatchLocationList + pPatch->PatchLocationListSubmissionStart, - pPatch->PatchLocationListSubmissionLength); - - // Record DMA buffer information - pDmaBufInfo->m_DmaBufState.m_bPatched = 1; - - return STATUS_SUCCESS; -} - -NTSTATUS -RosKmAdapter::CreateAllocation( - INOUT_PDXGKARG_CREATEALLOCATION pCreateAllocation) -{ - NT_ASSERT(pCreateAllocation->PrivateDriverDataSize == sizeof(RosAllocationGroupExchange)); - RosAllocationGroupExchange * pRosAllocationGroupExchange = (RosAllocationGroupExchange *)pCreateAllocation->pPrivateDriverData; - - pRosAllocationGroupExchange; - NT_ASSERT(pRosAllocationGroupExchange->m_dummy == 0); - - RosKmdResource * pRosKmdResource = NULL; - - if (pCreateAllocation->Flags.Resource) - { - if (pCreateAllocation->hResource == NULL) - { - pRosKmdResource = (RosKmdResource *)ExAllocatePoolWithTag(NonPagedPoolNx, sizeof(RosKmdResource), 'ROSD'); - if (!pRosKmdResource) - { - ROS_LOG_LOW_MEMORY( - "Failed to allocate nonpaged pool for sizeof(RosKmdResource) structure. (sizeof(RosKmdResource)=%d)", - sizeof(RosKmdResource)); - return STATUS_NO_MEMORY; - } - pRosKmdResource->m_dummy = 0; - } - else - { - pRosKmdResource = (RosKmdResource *)pCreateAllocation->hResource; - } - } - - NT_ASSERT(pCreateAllocation->NumAllocations == 1); - - DXGK_ALLOCATIONINFO * pAllocationInfo = pCreateAllocation->pAllocationInfo; - - NT_ASSERT(pAllocationInfo->PrivateDriverDataSize == sizeof(RosAllocationExchange)); - RosAllocationExchange * pRosAllocation = (RosAllocationExchange *)pAllocationInfo->pPrivateDriverData; - - RosKmdAllocation * pRosKmdAllocation = (RosKmdAllocation *)ExAllocatePoolWithTag(NonPagedPoolNx, sizeof(RosKmdAllocation), 'ROSD'); - if (!pRosKmdAllocation) - { - if (pRosKmdResource != NULL) ExFreePoolWithTag(pRosKmdResource, 'ROSD'); - - ROS_LOG_ERROR( - "Failed to allocated nonpaged pool for RosKmdAllocation. (sizeof(RosKmdAllocation)=%d)", - sizeof(RosKmdAllocation)); - return STATUS_NO_MEMORY; - } - - *(RosAllocationExchange *)pRosKmdAllocation = *pRosAllocation; - - pAllocationInfo->hAllocation = pRosKmdAllocation; - - pAllocationInfo->Alignment = 64; - pAllocationInfo->AllocationPriority = D3DDDI_ALLOCATIONPRIORITY_NORMAL; - pAllocationInfo->EvictionSegmentSet = 0; // don't use apperture for eviction - - pAllocationInfo->Flags.Value = 0; - - // - // Allocations should be marked CPU visible unless they are shared or - // can be flipped. - // Shared allocations (including the primary) cannot be CPU visible unless - // they are exclusively located in an aperture segment. - // - pAllocationInfo->Flags.CpuVisible = - !((pRosAllocation->m_miscFlags & D3D10_DDI_RESOURCE_MISC_SHARED) || - (pRosAllocation->m_bindFlags & D3D10_DDI_BIND_PRESENT)); - - // Allocations that will be flipped, such as the primary allocation, - // cannot be cached. - pAllocationInfo->Flags.Cached = pAllocationInfo->Flags.CpuVisible; - - pAllocationInfo->HintedBank.Value = 0; - pAllocationInfo->MaximumRenamingListLength = 0; - pAllocationInfo->pAllocationUsageHint = NULL; - pAllocationInfo->PhysicalAdapterIndex = 0; - pAllocationInfo->PitchAlignedSize = 0; - pAllocationInfo->PreferredSegment.Value = 0; - pAllocationInfo->PreferredSegment.SegmentId0 = ROSD_SEGMENT_VIDEO_MEMORY; - pAllocationInfo->PreferredSegment.Direction0 = 0; - - // zero-size allocations are not allowed - NT_ASSERT(pRosAllocation->m_hwSizeBytes != 0); - pAllocationInfo->Size = pRosAllocation->m_hwSizeBytes; - - pAllocationInfo->SupportedReadSegmentSet = 1 << (ROSD_SEGMENT_VIDEO_MEMORY - 1); - pAllocationInfo->SupportedWriteSegmentSet = 1 << (ROSD_SEGMENT_VIDEO_MEMORY - 1); - -#if GPU_CACHE_WORKAROUND - - if (pRosAllocation->m_bindFlags & D3D10_DDI_BIND_RENDER_TARGET) - { - pAllocationInfo->Size += m_rtSizeJitter; - - // - // Specific workaround for BasicTests.exe, ensures allocations use - // new memory range by enlarging the size of the render target - // - - m_rtSizeJitter += (5*kPageSize); - } - -#endif - - if (pCreateAllocation->Flags.Resource && pCreateAllocation->hResource == NULL && pRosKmdResource != NULL) - { - pCreateAllocation->hResource = pRosKmdResource; - } - - ROS_LOG_TRACE( - "Created allocation. (Flags.CpuVisible=%d, Flags.Cacheable=%d, Size=%Id)", - pAllocationInfo->Flags.CpuVisible, - pAllocationInfo->Flags.Cached, - pAllocationInfo->Size); - - return STATUS_SUCCESS; -} - -NTSTATUS -RosKmAdapter::DestroyAllocation( - IN_CONST_PDXGKARG_DESTROYALLOCATION pDestroyAllocation) -{ - RosKmdResource * pRosKmdResource = NULL; - - if (pDestroyAllocation->Flags.DestroyResource) - { - pRosKmdResource = (RosKmdResource *)pDestroyAllocation->hResource; - } - - NT_ASSERT(pDestroyAllocation->NumAllocations == 1); - RosKmdAllocation * pRosKmdAllocation = (RosKmdAllocation *)pDestroyAllocation->pAllocationList[0]; - - ExFreePoolWithTag(pRosKmdAllocation, 'ROSD'); - - if (pRosKmdResource != NULL) ExFreePoolWithTag(pRosKmdResource, 'ROSD'); - - return STATUS_SUCCESS; -} - -NTSTATUS -RosKmAdapter::QueryAdapterInfo( - IN_CONST_PDXGKARG_QUERYADAPTERINFO pQueryAdapterInfo) -{ - ROS_LOG_TRACE( - "QueryAdapterInfo was called. (Type=%d)", - pQueryAdapterInfo->Type); - - switch (pQueryAdapterInfo->Type) - { - case DXGKQAITYPE_UMDRIVERPRIVATE: - { - if (pQueryAdapterInfo->OutputDataSize < sizeof(ROSADAPTERINFO)) - { - ROS_LOG_ERROR( - "Output buffer is too small. (pQueryAdapterInfo->OutputDataSize=%d, sizeof(ROSADAPTERINFO)=%d)", - pQueryAdapterInfo->OutputDataSize, - sizeof(ROSADAPTERINFO)); - return STATUS_BUFFER_TOO_SMALL; - } - ROSADAPTERINFO* pRosAdapterInfo = (ROSADAPTERINFO*)pQueryAdapterInfo->pOutputData; - - pRosAdapterInfo->m_version = ROSD_VERSION; - pRosAdapterInfo->m_wddmVersion = m_WDDMVersion; - - // Software APCI device only claims an interrupt resource - pRosAdapterInfo->m_isSoftwareDevice = (m_flags.m_isVC4 != 1); - - RtlCopyMemory( - pRosAdapterInfo->m_deviceId, - m_deviceId, - m_deviceIdLength); - } - break; - - case DXGKQAITYPE_DRIVERCAPS: - { - if (pQueryAdapterInfo->OutputDataSize < sizeof(DXGK_DRIVERCAPS)) - { - ROS_LOG_ASSERTION( - "Output buffer is too small. (pQueryAdapterInfo->OutputDataSize=%d, sizeof(DXGK_DRIVERCAPS)=%d)", - pQueryAdapterInfo->OutputDataSize, - sizeof(DXGK_DRIVERCAPS)); - return STATUS_BUFFER_TOO_SMALL; - } - - DXGK_DRIVERCAPS *pDriverCaps = (DXGK_DRIVERCAPS *)pQueryAdapterInfo->pOutputData; - - // - // HighestAcceptableAddress - // - pDriverCaps->HighestAcceptableAddress.QuadPart = -1; - - // - // TODO[bhouse] MaxAllocationListSlotId - // - - // - // TODO[bhouse] ApertureSegmentCommitLimit - // - - // - // TODO[bhouse] MaxPointerWidth - // - - // - // TODO[bhouse] MaxPointerHeight - // - - // - // TODO[bhouse] PointerCaps - // - - // - // TODO[bhouse] InterruptMessageNumber - // - - // - // TODO[bhouse] NumberOfSwizzlingRanges - // - - // - // TODO[bhouse] MaxOverlays - // - - // - // TODO[bhouse] GammarRampCaps - // - - // - // TODO[bhouse] PresentationCaps - // - - pDriverCaps->PresentationCaps.SupportKernelModeCommandBuffer = FALSE; - pDriverCaps->PresentationCaps.SupportSoftwareDeviceBitmaps = TRUE; - - // - // Cap used for DWM off case, screen to screen blt is slow - // - pDriverCaps->PresentationCaps.NoScreenToScreenBlt = TRUE; - pDriverCaps->PresentationCaps.NoOverlapScreenBlt = TRUE; - - // - // Allow 16Kx16K (2 << (11 + 3)) texture(redirection device bitmap) - // - pDriverCaps->PresentationCaps.MaxTextureWidthShift = 3; - pDriverCaps->PresentationCaps.MaxTextureHeightShift = 3; - - // - // Use SW flip queue for flip with interval of 1 or more - // - we must NOT generate a DMA buffer in DxgkDdiPresent. That is, - // we must set the DXGKARG_PRESENT.pDmaBuffer output parameter - // to NULL. - // - DxgkDdiSetVidPnSourceAddress will be called at DIRQL - // - pDriverCaps->FlipCaps.FlipOnVSyncMmIo = TRUE; - - if (!RosKmdGlobal::IsRenderOnly()) - { - // - // The hardware can store at most one pending flip operation. - // - pDriverCaps->MaxQueuedFlipOnVSync = 1; - - // - // FlipOnVSyncWithNoWait - we don't have to wait for the next VSync - // to program in the new source address. We can program in the new - // source address and return immediately, and it will take - // effect at the next vsync. - // - pDriverCaps->FlipCaps.FlipOnVSyncWithNoWait = TRUE; - - // - // We do not support the scheduling of a flip command to take effect - // after two, three, or four vertical syncs. - // - pDriverCaps->FlipCaps.FlipInterval = FALSE; - - // - // The address we program into hardware does not take effect until - // the next vsync. - // - pDriverCaps->FlipCaps.FlipImmediateMmIo = FALSE; - - // - // WDDM 1.3 and later drivers must set this to TRUE. - // In an independent flip, the DWM user-mode present call is skipped - // and DxgkDdiPresent and DxgkDdiSetVidPnSourceAddress are called. - // - pDriverCaps->FlipCaps.FlipIndependent = TRUE; - - // - // TODO[jordanrh] VSyncPowerSaveAware - // https://msdn.microsoft.com/en-us/library/windows/hardware/ff569520(v=vs.85).aspx - // - } - - // - // TODO[bhouse] SchedulingCaps - // - -#if 1 - pDriverCaps->SchedulingCaps.MultiEngineAware = 1; -#endif - - // - // Set scheduling caps to indicate support for cancelling DMA buffer - // -#if 1 - pDriverCaps->SchedulingCaps.CancelCommandAware = 1; -#endif - - // - // Set scheduling caps to indicate driver is preemption aware - // -#if 1 - pDriverCaps->SchedulingCaps.PreemptionAware = 1; -#endif - - // - // TODO[bhouse] MemoryManagementCaps - // -#if 1 - pDriverCaps->MemoryManagementCaps.CrossAdapterResource = 1; -#endif - - // - // TODO[bhouse] GpuEngineTopology - // - - pDriverCaps->GpuEngineTopology.NbAsymetricProcessingNodes = m_NumNodes; - - // - // TODO[bhouse] WDDMVersion - // Documentation states that we should not set this value if WDDM 1.3 - // - pDriverCaps->WDDMVersion = m_WDDMVersion; - - // - // TODO[bhouse] VirtualAddressCaps - // - - // - // TODO[bhouse] DmaBufferCaps - // - - // - // TODO[bhouse] PreemptionCaps - // -#if 1 - pDriverCaps->PreemptionCaps.GraphicsPreemptionGranularity = D3DKMDT_GRAPHICS_PREEMPTION_PRIMITIVE_BOUNDARY; - pDriverCaps->PreemptionCaps.ComputePreemptionGranularity = D3DKMDT_COMPUTE_PREEMPTION_DISPATCH_BOUNDARY; -#endif - - // - // Must support DxgkDdiStopDeviceAndReleasePostDisplayOwnership - // - pDriverCaps->SupportNonVGA = TRUE; - - // - // Must support updating path rotation in DxgkDdiUpdateActiveVidPnPresentPath - // - pDriverCaps->SupportSmoothRotation = TRUE; - - // - // TODO[bhouse] SupportPerEngineTDR - // -#if 1 - pDriverCaps->SupportPerEngineTDR = 1; -#endif - - // - // SupportDirectFlip - // - must not allow video memory to be flipped to an incompatible - // allocation in DxgkDdiSetVidPnSourceAddress - // - the user mode driver must validate Direct Flip resources before - // the DWM uses them - // - pDriverCaps->SupportDirectFlip = 1; - - // - // TODO[bhouse] SupportMultiPlaneOverlay - // - - // - // Support SupportRuntimePowerManagement - // TODO[jordanrh] setting this to true causes constant power state transitions - // - pDriverCaps->SupportRuntimePowerManagement = FALSE; - - // - // TODO[bhouse] SupportSurpriseRemovalInHibernation - // - - // - // TODO[bhouse] HybridDiscrete - // - - // - // TODO[bhouse] MaxOverlayPlanes - // - - } - break; - - case DXGKQAITYPE_QUERYSEGMENT3: - { - if (pQueryAdapterInfo->OutputDataSize < sizeof(DXGK_QUERYSEGMENTOUT3)) - { - ROS_LOG_ASSERTION( - "Output buffer is too small. (pQueryAdapterInfo->OutputDataSize=%d, sizeof(DXGK_QUERYSEGMENTOUT3)=%d)", - pQueryAdapterInfo->OutputDataSize, - sizeof(DXGK_QUERYSEGMENTOUT3)); - return STATUS_BUFFER_TOO_SMALL; - } - - DXGK_QUERYSEGMENTOUT3 *pSegmentInfo = (DXGK_QUERYSEGMENTOUT3*)pQueryAdapterInfo->pOutputData; - - if (!pSegmentInfo[0].pSegmentDescriptor) - { - pSegmentInfo->NbSegment = 2; - } - else - { - DXGK_SEGMENTDESCRIPTOR3 *pSegmentDesc = pSegmentInfo->pSegmentDescriptor; - - // - // Private data size should be the maximum of UMD and KMD and the same size must - // be reported in DxgkDdiCreateContext for paging engine - // - pSegmentInfo->PagingBufferPrivateDataSize = sizeof(ROSUMDDMAPRIVATEDATA2); - - pSegmentInfo->PagingBufferSegmentId = ROSD_SEGMENT_APERTURE; - pSegmentInfo->PagingBufferSize = PAGE_SIZE; - - // - // Fill out aperture segment descriptor - // - memset(&pSegmentDesc[0], 0, sizeof(pSegmentDesc[0])); - - pSegmentDesc[0].Flags.Aperture = TRUE; - - // - // TODO[bhouse] What does marking it CacheCoherent mean? What are the side effects? - // What happens if we don't mark CacheCoherent? - // - pSegmentDesc[0].Flags.CacheCoherent = TRUE; - - // - // TODO[bhouse] BaseAddress should never be used. Do we need to set this still? - // - - pSegmentDesc[0].BaseAddress.QuadPart = ROSD_SEGMENT_APERTURE_BASE_ADDRESS; - - // - // Our fake apperture is not really visible and doesn't need to be. We - // still need to lie that it is visible reporting a bad physical address - // that will never be used. This is a legacy requirement of the DX stack. - // - - pSegmentDesc[0].CpuTranslatedAddress.QuadPart = 0xFFFFFFFE00000000; - pSegmentDesc[0].Flags.CpuVisible = TRUE; - - pSegmentDesc[0].Size = kApertureSegmentSize; - pSegmentDesc[0].CommitLimit = kApertureSegmentSize; - - // - // Setup local video memory segment - // - - memset(&pSegmentDesc[1], 0, sizeof(pSegmentDesc[1])); - - pSegmentDesc[1].BaseAddress.QuadPart = 0LL; // Gpu base physical address - pSegmentDesc[1].Flags.CpuVisible = true; - pSegmentDesc[1].Flags.CacheCoherent = true; - pSegmentDesc[1].Flags.DirectFlip = true; - pSegmentDesc[1].CpuTranslatedAddress = RosKmdGlobal::s_videoMemoryPhysicalAddress; // cpu base physical address - pSegmentDesc[1].Size = m_localVidMemSegmentSize; - - } - } - break; - - case DXGKQAITYPE_NUMPOWERCOMPONENTS: - { - if (pQueryAdapterInfo->OutputDataSize != sizeof(UINT)) - { - ROS_LOG_ASSERTION( - "Output buffer is unexpected size. (pQueryAdapterInfo->OutputDataSize=%d, sizeof(UINT)=%d)", - pQueryAdapterInfo->OutputDataSize, - sizeof(UINT)); - return STATUS_INVALID_PARAMETER; - } - - // - // Support only one 3D engine(s). - // - *(static_cast(pQueryAdapterInfo->pOutputData)) = GetNumPowerComponents(); - } - break; - - case DXGKQAITYPE_POWERCOMPONENTINFO: - { - if (pQueryAdapterInfo->InputDataSize != sizeof(UINT)) - { - ROS_LOG_ASSERTION( - "Input buffer is not of the expected size. (pQueryAdapterInfo->InputDataSize=%d, sizeof(UINT)=%d)", - pQueryAdapterInfo->InputDataSize, - sizeof(UINT)); - return STATUS_INVALID_PARAMETER; - } - - if (pQueryAdapterInfo->OutputDataSize < sizeof(DXGK_POWER_RUNTIME_COMPONENT)) - { - ROS_LOG_ASSERTION( - "Output buffer is too small. (pQueryAdapterInfo->OutputDataSize=%d, sizeof(DXGK_POWER_RUNTIME_COMPONENT)=%d)", - pQueryAdapterInfo->OutputDataSize, - sizeof(DXGK_POWER_RUNTIME_COMPONENT)); - return STATUS_BUFFER_TOO_SMALL; - } - - ULONG ComponentIndex = *(reinterpret_cast(pQueryAdapterInfo->pInputData)); - DXGK_POWER_RUNTIME_COMPONENT* pPowerComponent = reinterpret_cast(pQueryAdapterInfo->pOutputData); - - NTSTATUS status = GetPowerComponentInfo(ComponentIndex, pPowerComponent); - if (!NT_SUCCESS(status)) - { - ROS_LOG_ERROR( - "GetPowerComponentInfo(...) failed. (status=%!STATUS!, ComponentIndex=%d, pPowerComponent=0x%p)", - status, - ComponentIndex, - pPowerComponent); - return status; - } - } - break; - - case DXGKQAITYPE_HISTORYBUFFERPRECISION: - { - UINT NumStructures = pQueryAdapterInfo->OutputDataSize / sizeof(DXGKARG_HISTORYBUFFERPRECISION); - - for (UINT i = 0; i < NumStructures; i++) - { - DXGKARG_HISTORYBUFFERPRECISION *pHistoryBufferPrecision = ((DXGKARG_HISTORYBUFFERPRECISION *)pQueryAdapterInfo->pOutputData) + i; - - pHistoryBufferPrecision->PrecisionBits = 64; - } - - } - break; - - default: - ROS_LOG_WARNING( - "Unsupported query type. (pQueryAdapterInfo->Type=%d, pQueryAdapterInfo=0x%p)", - pQueryAdapterInfo->Type, - pQueryAdapterInfo); - return STATUS_NOT_SUPPORTED; - } - - return STATUS_SUCCESS; -} - -NTSTATUS -RosKmAdapter::DescribeAllocation( - INOUT_PDXGKARG_DESCRIBEALLOCATION pDescribeAllocation) -{ - RosKmdAllocation *pAllocation = (RosKmdAllocation *)pDescribeAllocation->hAllocation; - - pDescribeAllocation->Width = pAllocation->m_mip0Info.TexelWidth; - pDescribeAllocation->Height = pAllocation->m_mip0Info.TexelHeight; - pDescribeAllocation->Format = TranslateDxgiFormat(pAllocation->m_format); - - pDescribeAllocation->MultisampleMethod.NumSamples = pAllocation->m_sampleDesc.Count; - pDescribeAllocation->MultisampleMethod.NumQualityLevels = pAllocation->m_sampleDesc.Quality; - - pDescribeAllocation->RefreshRate.Numerator = pAllocation->m_primaryDesc.ModeDesc.RefreshRate.Numerator; - pDescribeAllocation->RefreshRate.Denominator = pAllocation->m_primaryDesc.ModeDesc.RefreshRate.Denominator; - - return STATUS_SUCCESS; - -} - -NTSTATUS -RosKmAdapter::GetNodeMetadata( - UINT NodeOrdinal, - OUT_PDXGKARG_GETNODEMETADATA pGetNodeMetadata - ) -{ - RtlZeroMemory(pGetNodeMetadata, sizeof(*pGetNodeMetadata)); - - pGetNodeMetadata->EngineType = DXGK_ENGINE_TYPE_3D; - - RtlStringCbPrintfW(pGetNodeMetadata->FriendlyName, - sizeof(pGetNodeMetadata->FriendlyName), - L"3DNode%02X", - NodeOrdinal); - - - return STATUS_SUCCESS; -} - - -NTSTATUS -RosKmAdapter::SubmitCommandVirtual( - IN_CONST_PDXGKARG_SUBMITCOMMANDVIRTUAL /*pSubmitCommandVirtual*/) -{ - ROS_LOG_ASSERTION("Not implemented"); - return STATUS_NOT_IMPLEMENTED; -} - -NTSTATUS -RosKmAdapter::PreemptCommand( - IN_CONST_PDXGKARG_PREEMPTCOMMAND /*pPreemptCommand*/) -{ - ROS_LOG_WARNING("Not implemented"); - return STATUS_SUCCESS; -} - -NTSTATUS -RosKmAdapter::RestartFromTimeout(void) -{ - ROS_LOG_ASSERTION("Not implemented"); - return STATUS_NOT_IMPLEMENTED; -} - -NTSTATUS -RosKmAdapter::CancelCommand( - IN_CONST_PDXGKARG_CANCELCOMMAND /*pCancelCommand*/) -{ - ROS_LOG_ASSERTION("Not implemented"); - return STATUS_NOT_IMPLEMENTED; -} - -NTSTATUS -RosKmAdapter::QueryCurrentFence( - INOUT_PDXGKARG_QUERYCURRENTFENCE pCurrentFence) -{ - ROS_LOG_WARNING("Not implemented"); - - NT_ASSERT(pCurrentFence->NodeOrdinal == 0); - NT_ASSERT(pCurrentFence->EngineOrdinal == 0); - - pCurrentFence->CurrentFence = 0; - return STATUS_SUCCESS; -} - -NTSTATUS -RosKmAdapter::ResetEngine( - INOUT_PDXGKARG_RESETENGINE /*pResetEngine*/) -{ - ROS_LOG_WARNING("Not implemented"); - return STATUS_SUCCESS; -} - -NTSTATUS -RosKmAdapter::CollectDbgInfo( - IN_CONST_PDXGKARG_COLLECTDBGINFO /*pCollectDbgInfo*/) -{ - ROS_LOG_WARNING("Not implemented"); - return STATUS_SUCCESS; -} - -NTSTATUS -RosKmAdapter::CreateProcess( - IN DXGKARG_CREATEPROCESS* /*pArgs*/) -{ - // pArgs->hKmdProcess = 0; - ROS_LOG_ASSERTION("Not implemented"); - return STATUS_NOT_IMPLEMENTED; -} - -NTSTATUS -RosKmAdapter::DestroyProcess( - IN HANDLE /*KmdProcessHandle*/) -{ - ROS_LOG_ASSERTION("Not implemented"); - return STATUS_NOT_IMPLEMENTED; -} - -void -RosKmAdapter::SetStablePowerState( - IN_CONST_PDXGKARG_SETSTABLEPOWERSTATE pArgs) -{ - UNREFERENCED_PARAMETER(pArgs); - ROS_LOG_ASSERTION("Not implemented"); -} - -NTSTATUS -RosKmAdapter::CalibrateGpuClock( - IN UINT32 /*NodeOrdinal*/, - IN UINT32 /*EngineOrdinal*/, - OUT_PDXGKARG_CALIBRATEGPUCLOCK /*pClockCalibration*/ - ) -{ - ROS_LOG_ASSERTION("Not implemented"); - return STATUS_NOT_IMPLEMENTED; -} - -NTSTATUS -RosKmAdapter::Escape( - IN_CONST_PDXGKARG_ESCAPE pEscape) -{ - NTSTATUS Status; - - if (pEscape->PrivateDriverDataSize < sizeof(UINT)) - { - ROS_LOG_ERROR( - "PrivateDriverDataSize is too small. (pEscape->PrivateDriverDataSize=%d, sizeof(UINT)=%d)", - pEscape->PrivateDriverDataSize, - sizeof(UINT)); - return STATUS_BUFFER_TOO_SMALL; - } - - UINT EscapeId = *((UINT *)pEscape->pPrivateDriverData); - -#pragma warning( disable : 4065 ) - switch (EscapeId) - { - - default: - - NT_ASSERT(false); - Status = STATUS_NOT_SUPPORTED; - break; - } - - ROS_LOG_ASSERTION("Not implemented"); - return STATUS_NOT_IMPLEMENTED; -} - -NTSTATUS -RosKmAdapter::ResetFromTimeout(void) -{ - ROS_LOG_ASSERTION("Not implemented"); - return STATUS_NOT_IMPLEMENTED; -} - -NTSTATUS -RosKmAdapter::QueryChildRelations( - INOUT_PDXGK_CHILD_DESCRIPTOR ChildRelations, - IN_ULONG ChildRelationsSize) -{ - if (RosKmdGlobal::IsRenderOnly()) - { - ROS_LOG_ASSERTION("QueryChildRelations() is not supported by render-only driver."); - return STATUS_NOT_IMPLEMENTED; - } - - return m_display.QueryChildRelations(ChildRelations, ChildRelationsSize); -} - -NTSTATUS -RosKmAdapter::QueryChildStatus( - IN_PDXGK_CHILD_STATUS ChildStatus, - IN_BOOLEAN NonDestructiveOnly) -{ - if (RosKmdGlobal::IsRenderOnly()) - { - ROS_LOG_ASSERTION("QueryChildStatus() is not supported by render-only driver."); - return STATUS_NOT_IMPLEMENTED; - } - - return m_display.QueryChildStatus(ChildStatus, NonDestructiveOnly); -} - -NTSTATUS -RosKmAdapter::QueryDeviceDescriptor( - IN_ULONG ChildUid, - INOUT_PDXGK_DEVICE_DESCRIPTOR pDeviceDescriptor) -{ - if (RosKmdGlobal::IsRenderOnly()) - { - ROS_LOG_ASSERTION("QueryChildStatus() is not supported by render-only driver."); - return STATUS_NOT_IMPLEMENTED; - } - - return m_display.QueryDeviceDescriptor(ChildUid, pDeviceDescriptor); -} - -NTSTATUS -RosKmAdapter::NotifyAcpiEvent( - IN_DXGK_EVENT_TYPE EventType, - IN_ULONG Event, - IN_PVOID Argument, - OUT_PULONG AcpiFlags) -{ - EventType; - Event; - Argument; - AcpiFlags; - - ROS_LOG_ASSERTION("Not implemented"); - return STATUS_NOT_IMPLEMENTED; -} - -void -RosKmAdapter::ResetDevice(void) -{ - // Do nothing - ROS_LOG_ASSERTION("Not implemented"); -} - -void -RosKmAdapter::PatchDmaBuffer( - ROSDMABUFINFO* pDmaBufInfo, - CONST DXGK_ALLOCATIONLIST* pAllocationList, - UINT allocationListSize, - CONST D3DDDI_PATCHLOCATIONLIST* pPatchLocationList, - UINT patchAllocationList) -{ - PBYTE pDmaBuf = (PBYTE)pDmaBufInfo->m_pDmaBuffer; - - for (UINT i = 0; i < patchAllocationList; i++) - { - auto patch = &pPatchLocationList[i]; - - allocationListSize; - NT_ASSERT(patch->AllocationIndex < allocationListSize); - - auto allocation = &pAllocationList[patch->AllocationIndex]; - - RosKmdDeviceAllocation * pRosKmdDeviceAllocation = (RosKmdDeviceAllocation *)allocation->hDeviceSpecificAllocation; - - if (allocation->SegmentId != 0) - { - DbgPrintEx(DPFLTR_IHVVIDEO_ID, DPFLTR_TRACE_LEVEL, "Patch RosKmdDeviceAllocation %lx at %lx\n", pRosKmdDeviceAllocation, allocation->PhysicalAddress); - DbgPrintEx(DPFLTR_IHVVIDEO_ID, DPFLTR_TRACE_LEVEL, "Patch buffer offset %lx allocation offset %lx\n", patch->PatchOffset, patch->AllocationOffset); - - // Patch in dma buffer - NT_ASSERT(allocation->SegmentId == ROSD_SEGMENT_VIDEO_MEMORY); - if (pDmaBufInfo->m_DmaBufState.m_bSwCommandBuffer) - { - PHYSICAL_ADDRESS allocAddress; - - allocAddress.QuadPart = allocation->PhysicalAddress.QuadPart + (LONGLONG)patch->AllocationOffset; - *((PHYSICAL_ADDRESS *)(pDmaBuf + patch->PatchOffset)) = allocAddress; - } - else - { - // Patch HW command buffer -#if VC4 - UINT physicalAddress = - RosKmdGlobal::s_videoMemoryPhysicalAddress.LowPart + - allocation->PhysicalAddress.LowPart + - patch->AllocationOffset; - - switch (patch->SlotId) - { - case VC4_SLOT_RT_BINNING_CONFIG: - pDmaBufInfo->m_RenderTargetPhysicalAddress = physicalAddress; - break; - case VC4_SLOT_TILE_ALLOCATION_MEMORY: - *((UINT *)(pDmaBuf + patch->PatchOffset)) = m_tileAllocationMemoryPhysicalAddress + m_busAddressOffset; - break; - case VC4_SLOT_TILE_STATE_DATA_ARRAY: - *((UINT *)(pDmaBuf + patch->PatchOffset)) = m_tileStateDataArrayPhysicalAddress + m_busAddressOffset; - break; - case VC4_SLOT_NV_SHADER_STATE: - case VC4_SLOT_BRANCH: - case VC4_SLOT_GL_SHADER_STATE: - case VC4_SLOT_FS_UNIFORM_ADDRESS: - case VC4_SLOT_VS_UNIFORM_ADDRESS: - case VC4_SLOT_CS_UNIFORM_ADDRESS: - // When PrePatch happens in DdiRender, DMA buffer physical - // address is not available, so DMA buffer self-reference - // patches are handled in SubmitCommand - break; - default: - *((UINT *)(pDmaBuf + patch->PatchOffset)) = physicalAddress + m_busAddressOffset; - } -#endif - } - } - } -} - -// -// TODO[indyz]: Add proper validation for DMA buffer -// -bool -RosKmAdapter::ValidateDmaBuffer( - ROSDMABUFINFO* pDmaBufInfo, - CONST DXGK_ALLOCATIONLIST* pAllocationList, - UINT allocationListSize, - CONST D3DDDI_PATCHLOCATIONLIST* pPatchLocationList, - UINT patchAllocationList) -{ - PBYTE pDmaBuf = (PBYTE)pDmaBufInfo->m_pDmaBuffer; - bool bValidateDmaBuffer = true; - ROSDMABUFSTATE* pDmaBufState = &pDmaBufInfo->m_DmaBufState; - - pDmaBuf; - - if (! pDmaBufInfo->m_DmaBufState.m_bSwCommandBuffer) - { - for (UINT i = 0; i < patchAllocationList; i++) - { - auto patch = &pPatchLocationList[i]; - - allocationListSize; - NT_ASSERT(patch->AllocationIndex < allocationListSize); - - auto allocation = &pAllocationList[patch->AllocationIndex]; - - RosKmdDeviceAllocation * pRosKmdDeviceAllocation = (RosKmdDeviceAllocation *)allocation->hDeviceSpecificAllocation; - -#if VC4 - - switch (patch->SlotId) - { - case VC4_SLOT_TILE_ALLOCATION_MEMORY: - if (pDmaBufState->m_bTileAllocMemRef) - { - return false; // Allow one per DMA buffer - } - else - { - pDmaBufState->m_bTileAllocMemRef = 1; - } - break; - case VC4_SLOT_TILE_STATE_DATA_ARRAY: - if (pDmaBufState->m_bTileStateDataRef) - { - return false; // Allow one per DMA buffer - } - else - { - pDmaBufState->m_bTileStateDataRef = 1; - } - break; - case VC4_SLOT_RT_BINNING_CONFIG: - if (pDmaBufState->m_bRenderTargetRef) - { - return false; // Allow one per DMA buffer - } - else - { - pDmaBufInfo->m_pRenderTarget = pRosKmdDeviceAllocation->m_pRosKmdAllocation; - pDmaBufState->m_bRenderTargetRef = 1; - } - break; - case VC4_SLOT_NV_SHADER_STATE: - case VC4_SLOT_BRANCH: - case VC4_SLOT_GL_SHADER_STATE: - case VC4_SLOT_FS_UNIFORM_ADDRESS: - case VC4_SLOT_VS_UNIFORM_ADDRESS: - case VC4_SLOT_CS_UNIFORM_ADDRESS: - if (pDmaBufState->m_NumDmaBufSelfRef == VC4_MAX_DMA_BUFFER_SELF_REF) - { - return false; // Allow up to VC4_MAX_DMA_BUFFER_SELF_REF - } - else - { - pDmaBufInfo->m_DmaBufSelfRef[pDmaBufState->m_NumDmaBufSelfRef] = *patch; - pDmaBufState->m_NumDmaBufSelfRef++; - } - break; - default: - break; - } - -#endif - } - - if ((0 == pDmaBufState->m_bRenderTargetRef) || - (0 == pDmaBufState->m_bTileAllocMemRef) || - (0 == pDmaBufState->m_bTileStateDataRef)) - { - bValidateDmaBuffer = false; - } - } - - return bValidateDmaBuffer; -} - -void -RosKmAdapter::QueueDmaBuffer( - IN_CONST_PDXGKARG_SUBMITCOMMAND pSubmitCommand) -{ - ROSDMABUFINFO * pDmaBufInfo = (ROSDMABUFINFO *)pSubmitCommand->pDmaBufferPrivateData; - KIRQL OldIrql; - ROSDMABUFSUBMISSION * pDmaBufSubmission; - - KeAcquireSpinLock(&m_dmaBufQueueLock, &OldIrql); - - // - // Combination indicating preparation error, thus the DMA buffer should be discarded - // - if ((pSubmitCommand->DmaBufferPhysicalAddress.QuadPart == 0) && - (pSubmitCommand->DmaBufferSubmissionStartOffset == 0) && - (pSubmitCommand->DmaBufferSubmissionEndOffset == 0)) - { - m_ErrorHit.m_PreparationError = 1; - } - - if (!pDmaBufInfo->m_DmaBufState.m_bSubmittedOnce) - { - pDmaBufInfo->m_DmaBufState.m_bSubmittedOnce = 1; - } - - NT_ASSERT(!IsListEmpty(&m_dmaBufSubmissionFree)); - - pDmaBufSubmission = CONTAINING_RECORD(RemoveHeadList(&m_dmaBufSubmissionFree), ROSDMABUFSUBMISSION, m_QueueEntry); - - pDmaBufSubmission->m_pDmaBufInfo = pDmaBufInfo; - - pDmaBufSubmission->m_StartOffset = pSubmitCommand->DmaBufferSubmissionStartOffset; - pDmaBufSubmission->m_EndOffset = pSubmitCommand->DmaBufferSubmissionEndOffset; - pDmaBufSubmission->m_SubmissionFenceId = pSubmitCommand->SubmissionFenceId; - - InsertTailList(&m_dmaBufQueue, &pDmaBufSubmission->m_QueueEntry); - - KeReleaseSpinLock(&m_dmaBufQueueLock, OldIrql); -} - -void -RosKmAdapter::HwDmaBufCompletionDpcRoutine( - KDPC *pDPC, - PVOID deferredContext, - PVOID systemArgument1, - PVOID systemArgument2) -{ - RosKmAdapter *pRosKmAdapter = RosKmAdapter::Cast(deferredContext); - - UNREFERENCED_PARAMETER(pDPC); - UNREFERENCED_PARAMETER(systemArgument1); - UNREFERENCED_PARAMETER(systemArgument2); - - // Signal to the worker thread that a HW DMA buffer has completed - KeSetEvent(&pRosKmAdapter->m_hwDmaBufCompletionEvent, 0, FALSE); -} - -ROS_NONPAGED_SEGMENT_BEGIN; //================================================ - -_Use_decl_annotations_ -NTSTATUS RosKmAdapter::SetVidPnSourceAddress ( - const DXGKARG_SETVIDPNSOURCEADDRESS* SetVidPnSourceAddressPtr - ) -{ - NT_ASSERT(!RosKmdGlobal::IsRenderOnly()); - return m_display.SetVidPnSourceAddress(SetVidPnSourceAddressPtr); -} - -ROS_NONPAGED_SEGMENT_END; //================================================== -ROS_PAGED_SEGMENT_BEGIN; //=================================================== - -_Use_decl_annotations_ -NTSTATUS RosKmAdapter::QueryInterface (QUERY_INTERFACE* Args) -{ - ROS_LOG_WARNING( - "Received QueryInterface for unsupported interface. (InterfaceType=%!GUID!)", - Args->InterfaceType); - return STATUS_NOT_SUPPORTED; -} - -_Use_decl_annotations_ -NTSTATUS RosKmAdapter::GetStandardAllocationDriverData ( - DXGKARG_GETSTANDARDALLOCATIONDRIVERDATA* Args - ) -{ - PAGED_CODE(); - ROS_ASSERT_MAX_IRQL(PASSIVE_LEVEL); - - // - // ResourcePrivateDriverDataSize gets passed to CreateAllocation as - // PrivateDriverDataSize. - // AllocationPrivateDriverDataSize get passed to CreateAllocation as - // pAllocationInfo->PrivateDriverDataSize. - // - - if (!Args->pResourcePrivateDriverData && !Args->pResourcePrivateDriverData) - { - Args->ResourcePrivateDriverDataSize = sizeof(RosAllocationGroupExchange); - Args->AllocationPrivateDriverDataSize = sizeof(RosAllocationExchange); - return STATUS_SUCCESS; - } - - // we expect them to both be null or both be valid - NT_ASSERT(Args->pResourcePrivateDriverData && Args->pResourcePrivateDriverData); - NT_ASSERT( - Args->ResourcePrivateDriverDataSize == - sizeof(RosAllocationGroupExchange)); - - NT_ASSERT( - Args->AllocationPrivateDriverDataSize == - sizeof(RosAllocationExchange)); - - new (Args->pResourcePrivateDriverData) RosAllocationGroupExchange(); - auto allocParams = new (Args->pAllocationPrivateDriverData) RosAllocationExchange(); - - switch (Args->StandardAllocationType) - { - case D3DKMDT_STANDARDALLOCATION_SHAREDPRIMARYSURFACE: - { - const D3DKMDT_SHAREDPRIMARYSURFACEDATA* surfData = - Args->pCreateSharedPrimarySurfaceData; - - ROS_LOG_TRACE( - "Preparing private allocation data for SHAREDPRIMARYSURFACEDATA. (Width=%d, Height=%d, Format=%d, RefreshRate=%d/%d, VidPnSourceId=%d)", - surfData->Width, - surfData->Height, - surfData->Format, - surfData->RefreshRate.Numerator, - surfData->RefreshRate.Denominator, - surfData->VidPnSourceId); - - allocParams->m_resourceDimension = D3D10DDIRESOURCE_TEXTURE2D; - allocParams->m_mip0Info.TexelWidth = surfData->Width; - allocParams->m_mip0Info.TexelHeight = surfData->Height; - allocParams->m_mip0Info.TexelDepth = 0; - allocParams->m_mip0Info.PhysicalWidth = surfData->Width; - allocParams->m_mip0Info.PhysicalHeight = surfData->Height; - allocParams->m_mip0Info.PhysicalDepth = 0; - - allocParams->m_usage = D3D10_DDI_USAGE_IMMUTABLE; - - // We must ensure that the D3D10_DDI_BIND_PRESENT is set so that - // CreateAllocation() creates an allocation that is suitable - // for the primary, which must be flippable. - // The primary cannot be cached. - allocParams->m_bindFlags = D3D10_DDI_BIND_RENDER_TARGET | D3D10_DDI_BIND_PRESENT; - - allocParams->m_mapFlags = 0; - - // The shared primary allocation is shared by definition - allocParams->m_miscFlags = D3D10_DDI_RESOURCE_MISC_SHARED; - - allocParams->m_format = DxgiFormatFromD3dDdiFormat(surfData->Format); - allocParams->m_sampleDesc.Count = 1; - allocParams->m_sampleDesc.Quality = 0; - allocParams->m_mipLevels = 1; - allocParams->m_arraySize = 1; - allocParams->m_isPrimary = true; - allocParams->m_primaryDesc.Flags = 0; - allocParams->m_primaryDesc.VidPnSourceId = surfData->VidPnSourceId; - allocParams->m_primaryDesc.ModeDesc.Width = surfData->Width; - allocParams->m_primaryDesc.ModeDesc.Height = surfData->Height; - allocParams->m_primaryDesc.ModeDesc.Format = DxgiFormatFromD3dDdiFormat(surfData->Format); - allocParams->m_primaryDesc.ModeDesc.RefreshRate.Numerator = surfData->RefreshRate.Numerator; - allocParams->m_primaryDesc.ModeDesc.RefreshRate.Denominator = surfData->RefreshRate.Denominator; - allocParams->m_primaryDesc.ModeDesc.ScanlineOrdering = DXGI_DDI_MODE_SCANLINE_ORDER_UNSPECIFIED; - allocParams->m_primaryDesc.ModeDesc.Rotation = DXGI_DDI_MODE_ROTATION_UNSPECIFIED; - allocParams->m_primaryDesc.ModeDesc.Scaling = DXGI_DDI_MODE_SCALING_UNSPECIFIED; - allocParams->m_primaryDesc.DriverFlags = 0; - - allocParams->m_hwLayout = RosHwLayout::Linear; - allocParams->m_hwWidthPixels = surfData->Width; - allocParams->m_hwHeightPixels = surfData->Height; - - NT_ASSERT(surfData->Format == D3DDDIFMT_A8R8G8B8); - allocParams->m_hwFormat = RosHwFormat::X8888; - allocParams->m_hwPitchBytes = surfData->Width * 4; - allocParams->m_hwSizeBytes = allocParams->m_hwPitchBytes * surfData->Height; - - return STATUS_SUCCESS; - } - case D3DKMDT_STANDARDALLOCATION_SHADOWSURFACE: - { - const D3DKMDT_SHADOWSURFACEDATA* surfData = Args->pCreateShadowSurfaceData; - ROS_LOG_TRACE( - "Preparing private allocation data for SHADOWSURFACE. (Width=%d, Height=%d, Format=%d)", - surfData->Width, - surfData->Height, - surfData->Format); - - allocParams->m_resourceDimension = D3D10DDIRESOURCE_TEXTURE2D; - allocParams->m_mip0Info.TexelWidth = surfData->Width; - allocParams->m_mip0Info.TexelHeight = surfData->Height; - allocParams->m_mip0Info.TexelDepth = 0; - allocParams->m_mip0Info.PhysicalWidth = surfData->Width; - allocParams->m_mip0Info.PhysicalHeight = surfData->Height; - allocParams->m_mip0Info.PhysicalDepth = 0; - allocParams->m_usage = D3D10_DDI_USAGE_DEFAULT; - - // The shadow allocation does not get flipped directly - static_assert( - !(D3D10_DDI_BIND_PIPELINE_MASK & D3D10_DDI_BIND_PRESENT), - "BIND_PRESENT must not be part of BIND_MASK"); - allocParams->m_bindFlags = D3D10_DDI_BIND_PIPELINE_MASK; - - allocParams->m_mapFlags = D3D10_DDI_MAP_READWRITE; - allocParams->m_miscFlags = D3D10_DDI_RESOURCE_MISC_SHARED; - - allocParams->m_format = DxgiFormatFromD3dDdiFormat(surfData->Format); - allocParams->m_sampleDesc.Count = 1; - allocParams->m_sampleDesc.Quality = 0; - allocParams->m_mipLevels = 1; - allocParams->m_arraySize = 1; - allocParams->m_isPrimary = true; - allocParams->m_primaryDesc.Flags = 0; - allocParams->m_primaryDesc.ModeDesc.Width = surfData->Width; - allocParams->m_primaryDesc.ModeDesc.Height = surfData->Height; - allocParams->m_primaryDesc.ModeDesc.Format = DxgiFormatFromD3dDdiFormat(surfData->Format); - allocParams->m_primaryDesc.DriverFlags = 0; - allocParams->m_hwLayout = RosHwLayout::Linear; - allocParams->m_hwWidthPixels = surfData->Width; - allocParams->m_hwHeightPixels = surfData->Height; - - NT_ASSERT(surfData->Format == D3DDDIFMT_A8R8G8B8); - allocParams->m_hwFormat = RosHwFormat::X8888; - allocParams->m_hwPitchBytes = surfData->Width * 4; - allocParams->m_hwSizeBytes = allocParams->m_hwPitchBytes * surfData->Height; - - Args->pCreateShadowSurfaceData->Pitch = allocParams->m_hwPitchBytes; - return STATUS_SUCCESS; - } - case D3DKMDT_STANDARDALLOCATION_STAGINGSURFACE: - { - const D3DKMDT_STAGINGSURFACEDATA* surfData = Args->pCreateStagingSurfaceData; - ROS_LOG_ASSERTION( - "STAGINGSURFACEDATA is not implemented. (Width=%d, Height=%d, Pitch=%d)", - surfData->Width, - surfData->Height, - surfData->Pitch); - return STATUS_NOT_IMPLEMENTED; - } - case D3DKMDT_STANDARDALLOCATION_GDISURFACE: - { - const D3DKMDT_GDISURFACEDATA* surfData = Args->pCreateGdiSurfaceData; - ROS_LOG_ASSERTION( - "GDISURFACEDATA is not implemented. We must return a nonzero Pitch if allocation is CPU visible. (Width=%d, Height=%d, Format=%d, Type=%d, Flags=0x%x, Pitch=%d)", - surfData->Width, - surfData->Height, - surfData->Format, - surfData->Type, - surfData->Flags.Value, - surfData->Pitch); - return STATUS_NOT_IMPLEMENTED; - } - default: - ROS_LOG_ASSERTION( - "Unknown standard allocation type. (StandardAllocationType=%d)", - Args->StandardAllocationType); - return STATUS_INVALID_PARAMETER; - } -} - -_Use_decl_annotations_ -NTSTATUS RosKmAdapter::SetPalette (const DXGKARG_SETPALETTE* /*SetPalettePtr*/) -{ - PAGED_CODE(); - ROS_ASSERT_MAX_IRQL(PASSIVE_LEVEL); - - ROS_LOG_ASSERTION("Not implemented."); - return STATUS_NOT_IMPLEMENTED; -} - -_Use_decl_annotations_ -NTSTATUS RosKmAdapter::SetPointerPosition ( - const DXGKARG_SETPOINTERPOSITION* SetPointerPositionPtr - ) -{ - PAGED_CODE(); - ROS_ASSERT_MAX_IRQL(PASSIVE_LEVEL); - - NT_ASSERT(!RosKmdGlobal::IsRenderOnly()); - return m_display.SetPointerPosition(SetPointerPositionPtr); -} - -_Use_decl_annotations_ -NTSTATUS RosKmAdapter::SetPointerShape ( - const DXGKARG_SETPOINTERSHAPE* SetPointerShapePtr - ) -{ - PAGED_CODE(); - ROS_ASSERT_MAX_IRQL(PASSIVE_LEVEL); - - NT_ASSERT(!RosKmdGlobal::IsRenderOnly()); - return m_display.SetPointerShape(SetPointerShapePtr); -} - -_Use_decl_annotations_ -NTSTATUS RosKmAdapter::IsSupportedVidPn ( - DXGKARG_ISSUPPORTEDVIDPN* IsSupportedVidPnPtr - ) -{ - PAGED_CODE(); - ROS_ASSERT_MAX_IRQL(PASSIVE_LEVEL); - - NT_ASSERT(!RosKmdGlobal::IsRenderOnly()); - return m_display.IsSupportedVidPn(IsSupportedVidPnPtr); -} - -_Use_decl_annotations_ -NTSTATUS RosKmAdapter::RecommendFunctionalVidPn ( - const DXGKARG_RECOMMENDFUNCTIONALVIDPN* const RecommendFunctionalVidPnPtr - ) -{ - PAGED_CODE(); - ROS_ASSERT_MAX_IRQL(PASSIVE_LEVEL); - - NT_ASSERT(!RosKmdGlobal::IsRenderOnly()); - return m_display.RecommendFunctionalVidPn(RecommendFunctionalVidPnPtr); -} - -_Use_decl_annotations_ -NTSTATUS RosKmAdapter::EnumVidPnCofuncModality ( - const DXGKARG_ENUMVIDPNCOFUNCMODALITY* const EnumCofuncModalityPtr - ) -{ - PAGED_CODE(); - ROS_ASSERT_MAX_IRQL(PASSIVE_LEVEL); - - NT_ASSERT(!RosKmdGlobal::IsRenderOnly()); - return m_display.EnumVidPnCofuncModality(EnumCofuncModalityPtr); -} - -_Use_decl_annotations_ -NTSTATUS RosKmAdapter::SetVidPnSourceVisibility ( - const DXGKARG_SETVIDPNSOURCEVISIBILITY* SetVidPnSourceVisibilityPtr - ) -{ - PAGED_CODE(); - ROS_ASSERT_MAX_IRQL(PASSIVE_LEVEL); - - NT_ASSERT(!RosKmdGlobal::IsRenderOnly()); - return m_display.SetVidPnSourceVisibility(SetVidPnSourceVisibilityPtr); -} - -_Use_decl_annotations_ -NTSTATUS RosKmAdapter::CommitVidPn ( - const DXGKARG_COMMITVIDPN* const CommitVidPnPtr - ) -{ - PAGED_CODE(); - ROS_ASSERT_MAX_IRQL(PASSIVE_LEVEL); - - NT_ASSERT(!RosKmdGlobal::IsRenderOnly()); - return m_display.CommitVidPn(CommitVidPnPtr); -} - -_Use_decl_annotations_ -NTSTATUS RosKmAdapter::UpdateActiveVidPnPresentPath ( - const DXGKARG_UPDATEACTIVEVIDPNPRESENTPATH* const UpdateActiveVidPnPresentPathPtr - ) -{ - PAGED_CODE(); - ROS_ASSERT_MAX_IRQL(PASSIVE_LEVEL); - - NT_ASSERT(!RosKmdGlobal::IsRenderOnly()); - return m_display.UpdateActiveVidPnPresentPath(UpdateActiveVidPnPresentPathPtr); -} - -_Use_decl_annotations_ -NTSTATUS RosKmAdapter::RecommendMonitorModes ( - const DXGKARG_RECOMMENDMONITORMODES* const RecommendMonitorModesPtr - ) -{ - PAGED_CODE(); - ROS_ASSERT_MAX_IRQL(PASSIVE_LEVEL); - - NT_ASSERT(!RosKmdGlobal::IsRenderOnly()); - return m_display.RecommendMonitorModes(RecommendMonitorModesPtr); -} - -_Use_decl_annotations_ -NTSTATUS RosKmAdapter::GetScanLine (DXGKARG_GETSCANLINE* /*GetScanLinePtr*/) -{ - PAGED_CODE(); - ROS_ASSERT_MAX_IRQL(PASSIVE_LEVEL); - - ROS_LOG_ASSERTION("Not implemented"); - return STATUS_NOT_IMPLEMENTED; -} - -_Use_decl_annotations_ -NTSTATUS RosKmAdapter::ControlInterrupt ( - const DXGK_INTERRUPT_TYPE InterruptType, - BOOLEAN EnableInterrupt - ) -{ - PAGED_CODE(); - ROS_ASSERT_MAX_IRQL(PASSIVE_LEVEL); - - NT_ASSERT(!RosKmdGlobal::IsRenderOnly()); - return m_display.ControlInterrupt(InterruptType, EnableInterrupt); -} - -_Use_decl_annotations_ -NTSTATUS RosKmAdapter::QueryVidPnHWCapability ( - DXGKARG_QUERYVIDPNHWCAPABILITY* VidPnHWCapsPtr - ) -{ - PAGED_CODE(); - ROS_ASSERT_MAX_IRQL(PASSIVE_LEVEL); - - NT_ASSERT(!RosKmdGlobal::IsRenderOnly()); - return m_display.QueryVidPnHWCapability(VidPnHWCapsPtr); -} - -_Use_decl_annotations_ -NTSTATUS RosKmAdapter::QueryDependentEngineGroup ( - DXGKARG_QUERYDEPENDENTENGINEGROUP* ArgsPtr - ) -{ - PAGED_CODE(); - ROS_ASSERT_MAX_IRQL(PASSIVE_LEVEL); - - NT_ASSERT(ArgsPtr->NodeOrdinal == 0); - NT_ASSERT(ArgsPtr->EngineOrdinal == 0); - - ArgsPtr->DependentNodeOrdinalMask = 0; - return STATUS_SUCCESS; -} - -_Use_decl_annotations_ -NTSTATUS RosKmAdapter::StopDeviceAndReleasePostDisplayOwnership ( - D3DDDI_VIDEO_PRESENT_TARGET_ID TargetId, - DXGK_DISPLAY_INFORMATION* DisplayInfoPtr - ) -{ - PAGED_CODE(); - ROS_ASSERT_MAX_IRQL(PASSIVE_LEVEL); - - NT_ASSERT(!RosKmdGlobal::IsRenderOnly()); - return m_display.StopDeviceAndReleasePostDisplayOwnership( - TargetId, - DisplayInfoPtr); -} - - -ROS_PAGED_SEGMENT_END; //===================================================== + +#include "precomp.h" + +#include "RosKmdLogging.h" +#include "RosKmdAdapter.tmh" + +#include "RosKmd.h" +#include "RosKmdAdapter.h" +#include "RosKmdRapAdapter.h" +#include "RosKmdSoftAdapter.h" +#include "RosKmdAllocation.h" +#include "RosKmdContext.h" +#include "RosKmdResource.h" +#include "RosKmdGlobal.h" +#include "RosKmdUtil.h" +#include "RosGpuCommand.h" +#include "RosKmdAcpi.h" +#include "RosKmdUtil.h" +#include "Vc4Hw.h" +#include "Vc4Ddi.h" +#include "Vc4Mailbox.h" + +void * RosKmAdapter::operator new(size_t size) +{ + return ExAllocatePoolWithTag(NonPagedPoolNx, size, 'ROSD'); +} + +void RosKmAdapter::operator delete(void * ptr) +{ + ExFreePool(ptr); +} + +RosKmAdapter::RosKmAdapter(IN_CONST_PDEVICE_OBJECT PhysicalDeviceObject, OUT_PPVOID MiniportDeviceContext) : + m_display(PhysicalDeviceObject, m_DxgkInterface, m_DxgkStartInfo, m_deviceInfo) +{ + m_magic = kMagic; + m_pPhysicalDevice = PhysicalDeviceObject; + + // Enable in RosKmAdapter::Start() when device is ready for interrupt + m_bReadyToHandleInterrupt = FALSE; + + // Set initial power management state. + m_PowerManagementStarted = FALSE; + m_AdapterPowerDState = PowerDeviceD0; // Device is at D0 at startup + m_NumPowerComponents = 0; + RtlZeroMemory(&m_EnginePowerFState[0], sizeof(m_EnginePowerFState)); // Components are F0 at startup. + + RtlZeroMemory(&m_deviceId, sizeof(m_deviceId)); + m_deviceIdLength = 0; + + m_flags.m_value = 0; + +#if VC4 + +#if GPU_CACHE_WORKAROUND + + m_rtSizeJitter = 0; + +#endif + + m_busAddressOffset = 0; + +#endif + + *MiniportDeviceContext = this; +} + +RosKmAdapter::~RosKmAdapter() +{ + // do nothing +} + +NTSTATUS +RosKmAdapter::AddAdapter( + IN_CONST_PDEVICE_OBJECT PhysicalDeviceObject, + OUT_PPVOID MiniportDeviceContext) +{ + NTSTATUS status; + WCHAR deviceID[512]; + ULONG dataLen; + + status = IoGetDeviceProperty(PhysicalDeviceObject, DevicePropertyHardwareID, sizeof(deviceID), deviceID, &dataLen); + if (!NT_SUCCESS(status)) + { + ROS_LOG_ERROR( + "Failed to get DevicePropertyHardwareID from PDO. (status=%!STATUS!)", + status); + return status; + } + + RosKmAdapter *pRosKmAdapter = nullptr; + if (wcscmp(deviceID, L"ACPI\\VEN_BCM&DEV_2850") == 0) + { + pRosKmAdapter = new RosKmdRapAdapter(PhysicalDeviceObject, MiniportDeviceContext); + if (!pRosKmAdapter) { + ROS_LOG_LOW_MEMORY("Failed to allocate RosKmdRapAdapter."); + return STATUS_NO_MEMORY; + } + } + else + { + pRosKmAdapter = new RosKmdSoftAdapter(PhysicalDeviceObject, MiniportDeviceContext); + if (!pRosKmAdapter) { + ROS_LOG_LOW_MEMORY("Failed to allocate RosKmdSoftAdapter."); + return STATUS_NO_MEMORY; + } + } + + return STATUS_SUCCESS; +} + +NTSTATUS +RosKmAdapter::QueryEngineStatus( + DXGKARG_QUERYENGINESTATUS *pQueryEngineStatus) +{ + ROS_LOG_TRACE("QueryEngineStatus was called."); + + pQueryEngineStatus->EngineStatus.Responsive = 1; + return STATUS_SUCCESS; +} + +void RosKmAdapter::WorkerThread(void * inThis) +{ + RosKmAdapter *pRosKmAdapter = RosKmAdapter::Cast(inThis); + + pRosKmAdapter->DoWork(); +} + +void RosKmAdapter::DoWork(void) +{ + bool done = false; + + while (!done) + { + NTSTATUS status = KeWaitForSingleObject( + &m_workerThreadEvent, + Executive, + KernelMode, + FALSE, + NULL); + + status; + NT_ASSERT(status == STATUS_SUCCESS); + + if (m_workerExit) + { + done = true; + continue; + } + + for (;;) + { + ROSDMABUFSUBMISSION * pDmaBufSubmission = DequeueDmaBuffer(&m_dmaBufQueueLock); + if (pDmaBufSubmission == NULL) + { + break; + } + + ROSDMABUFINFO * pDmaBufInfo = pDmaBufSubmission->m_pDmaBufInfo; + + if (pDmaBufInfo->m_DmaBufState.m_bPaging) + { + // + // Run paging buffer in software + // + + ProcessPagingBuffer(pDmaBufSubmission); + + NotifyDmaBufCompletion(pDmaBufSubmission); + } + else + { + // + // Process render DMA buffer + // + + ProcessRenderBuffer(pDmaBufSubmission); + + NotifyDmaBufCompletion(pDmaBufSubmission); + } + + ExInterlockedInsertTailList(&m_dmaBufSubmissionFree, &pDmaBufSubmission->m_QueueEntry, &m_dmaBufQueueLock); + } + } +} + +ROSDMABUFSUBMISSION * +RosKmAdapter::DequeueDmaBuffer( + KSPIN_LOCK *pDmaBufQueueLock) +{ + LIST_ENTRY *pDmaEntry; + + if (pDmaBufQueueLock) + { + pDmaEntry = ExInterlockedRemoveHeadList(&m_dmaBufQueue, pDmaBufQueueLock); + } + else + { + if (!IsListEmpty(&m_dmaBufQueue)) + { + pDmaEntry = RemoveHeadList(&m_dmaBufQueue); + } + else + { + pDmaEntry = NULL; + } + } + + return CONTAINING_RECORD(pDmaEntry, ROSDMABUFSUBMISSION, m_QueueEntry); +} + +void +RosKmAdapter::ProcessPagingBuffer( + ROSDMABUFSUBMISSION * pDmaBufSubmission) +{ + ROSDMABUFINFO * pDmaBufInfo = pDmaBufSubmission->m_pDmaBufInfo; + + NT_ASSERT(0 == (pDmaBufSubmission->m_EndOffset - pDmaBufSubmission->m_StartOffset) % sizeof(DXGKARG_BUILDPAGINGBUFFER)); + + DXGKARG_BUILDPAGINGBUFFER * pPagingBuffer = (DXGKARG_BUILDPAGINGBUFFER *)(pDmaBufInfo->m_pDmaBuffer + pDmaBufSubmission->m_StartOffset); + DXGKARG_BUILDPAGINGBUFFER * pEndofBuffer = (DXGKARG_BUILDPAGINGBUFFER *)(pDmaBufInfo->m_pDmaBuffer + pDmaBufSubmission->m_EndOffset); + + for (; pPagingBuffer < pEndofBuffer; pPagingBuffer++) + { + switch (pPagingBuffer->Operation) + { + case DXGK_OPERATION_FILL: + { + NT_ASSERT(pPagingBuffer->Fill.Destination.SegmentId == ROSD_SEGMENT_VIDEO_MEMORY); + NT_ASSERT(pPagingBuffer->Fill.FillSize % sizeof(ULONG) == 0); + + ULONG * const startAddress = reinterpret_cast( + (BYTE *)RosKmdGlobal::s_pVideoMemory + + pPagingBuffer->Fill.Destination.SegmentAddress.QuadPart); + for (ULONG * ptr = startAddress; + ptr != (startAddress + pPagingBuffer->Fill.FillSize / sizeof(ULONG)); + ++ptr) + { + *ptr = pPagingBuffer->Fill.FillPattern; + } + } + break; + case DXGK_OPERATION_TRANSFER: + { + PBYTE pSource, pDestination; + MDL * pMdlToRestore = NULL; + CSHORT savedMdlFlags = 0; + PBYTE pKmAddrToUnmap = NULL; + + if (pPagingBuffer->Transfer.Source.SegmentId == ROSD_SEGMENT_VIDEO_MEMORY) + { + pSource = ((BYTE *)RosKmdGlobal::s_pVideoMemory) + pPagingBuffer->Transfer.Source.SegmentAddress.QuadPart; + } + else + { + NT_ASSERT(pPagingBuffer->Transfer.Source.SegmentId == 0); + + pMdlToRestore = pPagingBuffer->Transfer.Source.pMdl; + savedMdlFlags = pMdlToRestore->MdlFlags; + + pSource = (PBYTE)MmGetSystemAddressForMdlSafe(pPagingBuffer->Transfer.Source.pMdl, HighPagePriority); + + pKmAddrToUnmap = pSource; + + // Adjust the source address by MdlOffset + pSource += (pPagingBuffer->Transfer.MdlOffset*PAGE_SIZE); + } + + if (pPagingBuffer->Transfer.Destination.SegmentId == ROSD_SEGMENT_VIDEO_MEMORY) + { + pDestination = ((BYTE *)RosKmdGlobal::s_pVideoMemory) + pPagingBuffer->Transfer.Destination.SegmentAddress.QuadPart; + } + else + { + NT_ASSERT(pPagingBuffer->Transfer.Destination.SegmentId == 0); + + pMdlToRestore = pPagingBuffer->Transfer.Destination.pMdl; + savedMdlFlags = pMdlToRestore->MdlFlags; + + pDestination = (PBYTE)MmGetSystemAddressForMdlSafe(pPagingBuffer->Transfer.Destination.pMdl, HighPagePriority); + + pKmAddrToUnmap = pDestination; + + // Adjust the destination address by MdlOffset + pDestination += (pPagingBuffer->Transfer.MdlOffset*PAGE_SIZE); + } + + if (pSource && pDestination) + { + RtlCopyMemory(pDestination, pSource, pPagingBuffer->Transfer.TransferSize); + } + else + { + // TODO[indyz]: Propagate the error back to runtime + m_ErrorHit.m_PagingFailure = 1; + } + + // Restore the state of the Mdl (for source or destionation) + if ((0 == (savedMdlFlags & MDL_MAPPED_TO_SYSTEM_VA)) && pKmAddrToUnmap) + { + MmUnmapLockedPages(pKmAddrToUnmap, pMdlToRestore); + } + } + break; + + default: + NT_ASSERT(false); + } + } +} + +void +RosKmAdapter::NotifyDmaBufCompletion( + ROSDMABUFSUBMISSION * pDmaBufSubmission) +{ + ROSDMABUFINFO * pDmaBufInfo = pDmaBufSubmission->m_pDmaBufInfo; + + if (! pDmaBufInfo->m_DmaBufState.m_bPaging) + { + pDmaBufInfo->m_DmaBufState.m_bCompleted = 1; + } + + // + // Notify the VidSch of the completion of the DMA buffer + // + NTSTATUS Status; + + RtlZeroMemory(&m_interruptData, sizeof(m_interruptData)); + + m_interruptData.InterruptType = DXGK_INTERRUPT_DMA_COMPLETED; + m_interruptData.DmaCompleted.SubmissionFenceId = pDmaBufSubmission->m_SubmissionFenceId; + m_interruptData.DmaCompleted.NodeOrdinal = 0; + m_interruptData.DmaCompleted.EngineOrdinal = 0; + + BOOLEAN bRet; + + Status = m_DxgkInterface.DxgkCbSynchronizeExecution( + m_DxgkInterface.DeviceHandle, + SynchronizeNotifyInterrupt, + this, + 0, + &bRet); + + if (!NT_SUCCESS(Status)) + { + m_ErrorHit.m_NotifyDmaBufCompletion = 1; + } +} + +BOOLEAN RosKmAdapter::SynchronizeNotifyInterrupt(PVOID inThis) +{ + RosKmAdapter *pRosKmAdapter = RosKmAdapter::Cast(inThis); + + return pRosKmAdapter->SynchronizeNotifyInterrupt(); +} + +BOOLEAN RosKmAdapter::SynchronizeNotifyInterrupt(void) +{ + m_DxgkInterface.DxgkCbNotifyInterrupt(m_DxgkInterface.DeviceHandle, &m_interruptData); + + return m_DxgkInterface.DxgkCbQueueDpc(m_DxgkInterface.DeviceHandle); +} + +NTSTATUS +RosKmAdapter::Start( + IN_PDXGK_START_INFO DxgkStartInfo, + IN_PDXGKRNL_INTERFACE DxgkInterface, + OUT_PULONG NumberOfVideoPresentSources, + OUT_PULONG NumberOfChildren) +{ + m_DxgkStartInfo = *DxgkStartInfo; + m_DxgkInterface = *DxgkInterface; + + // + // Render only device has no VidPn source and target + // Subclass should overwrite these values if it is not render-only. + // + *NumberOfVideoPresentSources = 0; + *NumberOfChildren = 0; + + // + // Sample for 1.3 model currently + // + m_WDDMVersion = DXGKDDI_WDDMv1_3; + + m_NumNodes = C_ROSD_GPU_ENGINE_COUNT; + + // + // Initialize worker + // + + KeInitializeEvent(&m_workerThreadEvent, SynchronizationEvent, FALSE); + + m_workerExit = false; + + OBJECT_ATTRIBUTES ObjectAttributes; + HANDLE hWorkerThread; + + InitializeObjectAttributes(&ObjectAttributes, NULL, OBJ_KERNEL_HANDLE, NULL, NULL); + + NTSTATUS status = PsCreateSystemThread( + &hWorkerThread, + THREAD_ALL_ACCESS, + &ObjectAttributes, + NULL, + NULL, + (PKSTART_ROUTINE) RosKmAdapter::WorkerThread, + this); + + if (status != STATUS_SUCCESS) + { + ROS_LOG_ERROR( + "PsCreateSystemThread(...) failed for RosKmAdapter::WorkerThread. (status=%!STATUS!)", + status); + return status; + } + + status = ObReferenceObjectByHandle( + hWorkerThread, + THREAD_ALL_ACCESS, + *PsThreadType, + KernelMode, + (PVOID *)&m_pWorkerThread, + NULL); + + ZwClose(hWorkerThread); + + if (!NT_SUCCESS(status)) + { + ROS_LOG_ERROR( + "ObReferenceObjectByHandle(...) failed for worker thread. (status=%!STATUS!)", + status); + return status; + } + + status = m_DxgkInterface.DxgkCbGetDeviceInformation( + m_DxgkInterface.DeviceHandle, + &m_deviceInfo); + if (!NT_SUCCESS(status)) + { + ROS_LOG_ERROR( + "DxgkCbGetDeviceInformation(...) failed. (status=%!STATUS!, m_DxgkInterface.DeviceHandle=0x%p)", + status, + m_DxgkInterface.DeviceHandle); + return status; + } + + // + // Query APCI device ID + // + { + NTSTATUS acpiStatus; + + RosKmAcpiReader acpiReader(this, DISPLAY_ADAPTER_HW_ID); + acpiStatus = acpiReader.Read(ACPI_METHOD_HARDWARE_ID); + if (NT_SUCCESS(acpiStatus) && (acpiReader.GetOutputArgumentCount() == 1)) + { + RosKmAcpiArgumentParser acpiParser(&acpiReader, NULL); + char *pDeviceId; + ULONG DeviceIdLength; + acpiStatus = acpiParser.GetAnsiString(&pDeviceId, &DeviceIdLength); + if (NT_SUCCESS(acpiStatus) && DeviceIdLength) + { + m_deviceIdLength = min(DeviceIdLength, sizeof(m_deviceId)); + RtlCopyMemory(&m_deviceId[0], pDeviceId, m_deviceIdLength); + } + } + } + + // + // Initialize power component data. + // + InitializePowerComponentInfo(); + + // + // Initialize apperture state + // + + memset(m_aperturePageTable, 0, sizeof(m_aperturePageTable)); + + // + // Intialize DMA buffer queue and lock + // + + InitializeListHead(&m_dmaBufSubmissionFree); + for (UINT i = 0; i < m_maxDmaBufQueueLength; i++) + { + InsertHeadList(&m_dmaBufSubmissionFree, &m_dmaBufSubssions[i].m_QueueEntry); + } + + InitializeListHead(&m_dmaBufQueue); + KeInitializeSpinLock(&m_dmaBufQueueLock); + + // + // Initialize HW DMA buffer compeletion DPC and event + // + + KeInitializeEvent(&m_hwDmaBufCompletionEvent, SynchronizationEvent, FALSE); + KeInitializeDpc(&m_hwDmaBufCompletionDpc, HwDmaBufCompletionDpcRoutine, this); + + ROS_LOG_TRACE("Adapter was successfully started."); + return STATUS_SUCCESS; +} + +NTSTATUS +RosKmAdapter::Stop() +{ + m_workerExit = true; + + KeSetEvent(&m_workerThreadEvent, 0, FALSE); + + NTSTATUS status = KeWaitForSingleObject( + m_pWorkerThread, + Executive, + KernelMode, + FALSE, + NULL); + + status; + NT_ASSERT(status == STATUS_SUCCESS); + + ObDereferenceObject(m_pWorkerThread); + + ROS_LOG_TRACE("Adapter was successfully stopped."); + return STATUS_SUCCESS; +} + +void RosKmAdapter::DpcRoutine(void) +{ + // dp nothing other than calling back into dxgk + + m_DxgkInterface.DxgkCbNotifyDpc(m_DxgkInterface.DeviceHandle); +} + +NTSTATUS +RosKmAdapter::BuildPagingBuffer( + IN_PDXGKARG_BUILDPAGINGBUFFER pArgs) +{ + NTSTATUS Status = STATUS_SUCCESS; + PBYTE pDmaBufStart = (PBYTE)pArgs->pDmaBuffer; + PBYTE pDmaBufPos = (PBYTE)pArgs->pDmaBuffer; + + // + // hAllocation is NULL for operation on DMA buffer and pages mapped into aperture + // + + // + // If there is insufficient space left in DMA buffer, we should return + // STATUS_GRAPHICS_INSUFFICIENT_DMA_BUFFER. + // + + switch (pArgs->Operation) + { + case DXGK_OPERATION_MAP_APERTURE_SEGMENT: + { + if (pArgs->MapApertureSegment.SegmentId == kApertureSegmentId) + { + size_t pageIndex = pArgs->MapApertureSegment.OffsetInPages; + size_t pageCount = pArgs->MapApertureSegment.NumberOfPages; + + NT_ASSERT(pageIndex + pageCount <= kApertureSegmentPageCount); + + size_t mdlPageOffset = pArgs->MapApertureSegment.MdlOffset; + + PMDL pMdl = pArgs->MapApertureSegment.pMdl; + + for (UINT i = 0; i < pageCount; i++) + { + m_aperturePageTable[pageIndex + i] = MmGetMdlPfnArray(pMdl)[mdlPageOffset + i]; + } + } + + } + break; + + case DXGK_OPERATION_UNMAP_APERTURE_SEGMENT: + { + if (pArgs->MapApertureSegment.SegmentId == kApertureSegmentId) + { + size_t pageIndex = pArgs->MapApertureSegment.OffsetInPages; + size_t pageCount = pArgs->MapApertureSegment.NumberOfPages; + + NT_ASSERT(pageIndex + pageCount <= kApertureSegmentPageCount); + + while (pageCount--) + { + m_aperturePageTable[pageIndex++] = 0; + } + } + } + + break; + + case DXGK_OPERATION_FILL: + { + RosKmdAllocation * pRosKmdAllocation = (RosKmdAllocation *)pArgs->Fill.hAllocation; + pRosKmdAllocation; + + ROS_LOG_TRACE( + "Filling DMA buffer. (Destination.SegmentAddress=0x%I64x, FillPattern=0x%lx, FillSize=%Id)", + pArgs->Fill.Destination.SegmentAddress.QuadPart, + pArgs->Fill.FillPattern, + pArgs->Fill.FillSize); + + if (pArgs->DmaSize < sizeof(DXGKARG_BUILDPAGINGBUFFER)) + { + ROS_LOG_ERROR( + "DXGK_OPERATION_FILL: DMA buffer size is too small. (pArgs->DmaSize=%d, sizeof(DXGKARG_BUILDPAGINGBUFFER)=%d)", + pArgs->DmaSize, + sizeof(DXGKARG_BUILDPAGINGBUFFER)); + return STATUS_GRAPHICS_INSUFFICIENT_DMA_BUFFER; + } + else + { + *((DXGKARG_BUILDPAGINGBUFFER *)pArgs->pDmaBuffer) = *pArgs; + + pDmaBufPos += sizeof(DXGKARG_BUILDPAGINGBUFFER); + } + } + break; + + case DXGK_OPERATION_DISCARD_CONTENT: + { + // do nothing + } + break; + + case DXGK_OPERATION_TRANSFER: + { + if (pArgs->DmaSize < sizeof(DXGKARG_BUILDPAGINGBUFFER)) + { + ROS_LOG_ERROR( + "DXGK_OPERATION_TRANSFER: DMA buffer is too small. (pArgs->DmaSize=%d, sizeof(DXGKARG_BUILDPAGINGBUFFER)=%d)", + pArgs->DmaSize, + sizeof(DXGKARG_BUILDPAGINGBUFFER)); + return STATUS_GRAPHICS_INSUFFICIENT_DMA_BUFFER; + } + else + { + *((DXGKARG_BUILDPAGINGBUFFER *)pArgs->pDmaBuffer) = *pArgs; + + pDmaBufPos += sizeof(DXGKARG_BUILDPAGINGBUFFER); + } + } + break; + + default: + { + NT_ASSERT(false); + + m_ErrorHit.m_UnSupportedPagingOp = 1; + Status = STATUS_SUCCESS; + } + break; + } + + // + // Update pDmaBuffer to point past the last byte used. + pArgs->pDmaBuffer = pDmaBufPos; + + // Record DMA buffer information only when it is newly used + ROSDMABUFINFO * pDmaBufInfo = (ROSDMABUFINFO *)pArgs->pDmaBufferPrivateData; + if (pDmaBufInfo && (pArgs->DmaSize == ROSD_PAGING_BUFFER_SIZE)) + { + pDmaBufInfo->m_DmaBufState.m_Value = 0; + pDmaBufInfo->m_DmaBufState.m_bPaging = 1; + + pDmaBufInfo->m_pDmaBuffer = pDmaBufStart; + pDmaBufInfo->m_DmaBufferSize = pArgs->DmaSize; + } + + return Status; +} + +NTSTATUS +RosKmAdapter::DispatchIoRequest( + IN_ULONG VidPnSourceId, + IN_PVIDEO_REQUEST_PACKET VideoRequestPacket) +{ + if (RosKmdGlobal::IsRenderOnly()) + { + ROS_LOG_WARNING( + "Unsupported IO Control Code. (VideoRequestPacketPtr->IoControlCode = 0x%lx)", + VideoRequestPacket->IoControlCode); + return STATUS_NOT_SUPPORTED; + } + + return m_display.DispatchIoRequest(VidPnSourceId, VideoRequestPacket); +} + +NTSTATUS +RosKmAdapter::SubmitCommand( + IN_CONST_PDXGKARG_SUBMITCOMMAND pSubmitCommand) +{ + NTSTATUS Status = STATUS_SUCCESS; + +#if VC4 + + if (!pSubmitCommand->Flags.Paging) + { + // + // Patch DMA buffer self-reference + // + ROSDMABUFINFO *pDmaBufInfo = (ROSDMABUFINFO *)pSubmitCommand->pDmaBufferPrivateData; + BYTE *pDmaBuf = pDmaBufInfo->m_pDmaBuffer; + UINT dmaBufPhysicalAddress; + + // + // Need to record DMA buffer physical address for fully pre-patched DMA buffer + // + pDmaBufInfo->m_DmaBufferPhysicalAddress = pSubmitCommand->DmaBufferPhysicalAddress; + + dmaBufPhysicalAddress = GetAperturePhysicalAddress( + pSubmitCommand->DmaBufferPhysicalAddress.LowPart); + + for (UINT i = 0; i < pDmaBufInfo->m_DmaBufState.m_NumDmaBufSelfRef; i++) + { + D3DDDI_PATCHLOCATIONLIST *pPatchLoc = &pDmaBufInfo->m_DmaBufSelfRef[i]; + + *((UINT *)(pDmaBuf + pPatchLoc->PatchOffset)) = + dmaBufPhysicalAddress + + m_busAddressOffset + + pPatchLoc->AllocationOffset; + } + } + +#endif + + // NOTE: pRosKmContext will be NULL for paging operations + RosKmContext *pRosKmContext = (RosKmContext *)pSubmitCommand->hContext; + pRosKmContext; + + QueueDmaBuffer(pSubmitCommand); + + // + // Wake up the worker thread for the GPU node + // + KeSetEvent(&m_workerThreadEvent, 0, FALSE); + + return Status; +} + +NTSTATUS +RosKmAdapter::Patch( + IN_CONST_PDXGKARG_PATCH pPatch) +{ + ROSDMABUFINFO *pDmaBufInfo = (ROSDMABUFINFO *)pPatch->pDmaBufferPrivateData; + + RosKmContext * pRosKmContext = (RosKmContext *)pPatch->hContext; + pRosKmContext; + + pDmaBufInfo->m_DmaBufferPhysicalAddress = pPatch->DmaBufferPhysicalAddress; + + PatchDmaBuffer( + pDmaBufInfo, + pPatch->pAllocationList, + pPatch->AllocationListSize, + pPatch->pPatchLocationList + pPatch->PatchLocationListSubmissionStart, + pPatch->PatchLocationListSubmissionLength); + + // Record DMA buffer information + pDmaBufInfo->m_DmaBufState.m_bPatched = 1; + + return STATUS_SUCCESS; +} + +NTSTATUS +RosKmAdapter::CreateAllocation( + INOUT_PDXGKARG_CREATEALLOCATION pCreateAllocation) +{ + NT_ASSERT(pCreateAllocation->PrivateDriverDataSize == sizeof(RosAllocationGroupExchange)); + RosAllocationGroupExchange * pRosAllocationGroupExchange = (RosAllocationGroupExchange *)pCreateAllocation->pPrivateDriverData; + + pRosAllocationGroupExchange; + NT_ASSERT(pRosAllocationGroupExchange->m_dummy == 0); + + RosKmdResource * pRosKmdResource = NULL; + + if (pCreateAllocation->Flags.Resource) + { + if (pCreateAllocation->hResource == NULL) + { + pRosKmdResource = (RosKmdResource *)ExAllocatePoolWithTag(NonPagedPoolNx, sizeof(RosKmdResource), 'ROSD'); + if (!pRosKmdResource) + { + ROS_LOG_LOW_MEMORY( + "Failed to allocate nonpaged pool for sizeof(RosKmdResource) structure. (sizeof(RosKmdResource)=%d)", + sizeof(RosKmdResource)); + return STATUS_NO_MEMORY; + } + pRosKmdResource->m_dummy = 0; + } + else + { + pRosKmdResource = (RosKmdResource *)pCreateAllocation->hResource; + } + } + + NT_ASSERT(pCreateAllocation->NumAllocations == 1); + + DXGK_ALLOCATIONINFO * pAllocationInfo = pCreateAllocation->pAllocationInfo; + + NT_ASSERT(pAllocationInfo->PrivateDriverDataSize == sizeof(RosAllocationExchange)); + RosAllocationExchange * pRosAllocation = (RosAllocationExchange *)pAllocationInfo->pPrivateDriverData; + + RosKmdAllocation * pRosKmdAllocation = (RosKmdAllocation *)ExAllocatePoolWithTag(NonPagedPoolNx, sizeof(RosKmdAllocation), 'ROSD'); + if (!pRosKmdAllocation) + { + if (pRosKmdResource != NULL) ExFreePoolWithTag(pRosKmdResource, 'ROSD'); + + ROS_LOG_ERROR( + "Failed to allocated nonpaged pool for RosKmdAllocation. (sizeof(RosKmdAllocation)=%d)", + sizeof(RosKmdAllocation)); + return STATUS_NO_MEMORY; + } + + *(RosAllocationExchange *)pRosKmdAllocation = *pRosAllocation; + + pAllocationInfo->hAllocation = pRosKmdAllocation; + + pAllocationInfo->Alignment = 64; + pAllocationInfo->AllocationPriority = D3DDDI_ALLOCATIONPRIORITY_NORMAL; + pAllocationInfo->EvictionSegmentSet = 0; // don't use apperture for eviction + + pAllocationInfo->Flags.Value = 0; + + // + // Allocations should be marked CPU visible unless they are shared or + // can be flipped. + // Shared allocations (including the primary) cannot be CPU visible unless + // they are exclusively located in an aperture segment. + // + pAllocationInfo->Flags.CpuVisible = + !((pRosAllocation->m_miscFlags & D3D10_DDI_RESOURCE_MISC_SHARED) || + (pRosAllocation->m_bindFlags & D3D10_DDI_BIND_PRESENT)); + + // Allocations that will be flipped, such as the primary allocation, + // cannot be cached. + pAllocationInfo->Flags.Cached = pAllocationInfo->Flags.CpuVisible; + + pAllocationInfo->HintedBank.Value = 0; + pAllocationInfo->MaximumRenamingListLength = 0; + pAllocationInfo->pAllocationUsageHint = NULL; + pAllocationInfo->PhysicalAdapterIndex = 0; + pAllocationInfo->PitchAlignedSize = 0; + pAllocationInfo->PreferredSegment.Value = 0; + pAllocationInfo->PreferredSegment.SegmentId0 = ROSD_SEGMENT_VIDEO_MEMORY; + pAllocationInfo->PreferredSegment.Direction0 = 0; + + // zero-size allocations are not allowed + NT_ASSERT(pRosAllocation->m_hwSizeBytes != 0); + pAllocationInfo->Size = pRosAllocation->m_hwSizeBytes; + + pAllocationInfo->SupportedReadSegmentSet = 1 << (ROSD_SEGMENT_VIDEO_MEMORY - 1); + pAllocationInfo->SupportedWriteSegmentSet = 1 << (ROSD_SEGMENT_VIDEO_MEMORY - 1); + +#if GPU_CACHE_WORKAROUND + + if (pRosAllocation->m_bindFlags & D3D10_DDI_BIND_RENDER_TARGET) + { + pAllocationInfo->Size += m_rtSizeJitter; + + // + // Specific workaround for BasicTests.exe, ensures allocations use + // new memory range by enlarging the size of the render target + // + + m_rtSizeJitter += (5*kPageSize); + } + +#endif + + if (pCreateAllocation->Flags.Resource && pCreateAllocation->hResource == NULL && pRosKmdResource != NULL) + { + pCreateAllocation->hResource = pRosKmdResource; + } + + ROS_LOG_TRACE( + "Created allocation. (Flags.CpuVisible=%d, Flags.Cacheable=%d, Size=%Id)", + pAllocationInfo->Flags.CpuVisible, + pAllocationInfo->Flags.Cached, + pAllocationInfo->Size); + + return STATUS_SUCCESS; +} + +NTSTATUS +RosKmAdapter::DestroyAllocation( + IN_CONST_PDXGKARG_DESTROYALLOCATION pDestroyAllocation) +{ + RosKmdResource * pRosKmdResource = NULL; + + if (pDestroyAllocation->Flags.DestroyResource) + { + pRosKmdResource = (RosKmdResource *)pDestroyAllocation->hResource; + } + + NT_ASSERT(pDestroyAllocation->NumAllocations == 1); + RosKmdAllocation * pRosKmdAllocation = (RosKmdAllocation *)pDestroyAllocation->pAllocationList[0]; + + ExFreePoolWithTag(pRosKmdAllocation, 'ROSD'); + + if (pRosKmdResource != NULL) ExFreePoolWithTag(pRosKmdResource, 'ROSD'); + + return STATUS_SUCCESS; +} + +NTSTATUS +RosKmAdapter::QueryAdapterInfo( + IN_CONST_PDXGKARG_QUERYADAPTERINFO pQueryAdapterInfo) +{ + ROS_LOG_TRACE( + "QueryAdapterInfo was called. (Type=%d)", + pQueryAdapterInfo->Type); + + switch (pQueryAdapterInfo->Type) + { + case DXGKQAITYPE_UMDRIVERPRIVATE: + { + if (pQueryAdapterInfo->OutputDataSize < sizeof(ROSADAPTERINFO)) + { + ROS_LOG_ERROR( + "Output buffer is too small. (pQueryAdapterInfo->OutputDataSize=%d, sizeof(ROSADAPTERINFO)=%d)", + pQueryAdapterInfo->OutputDataSize, + sizeof(ROSADAPTERINFO)); + return STATUS_BUFFER_TOO_SMALL; + } + ROSADAPTERINFO* pRosAdapterInfo = (ROSADAPTERINFO*)pQueryAdapterInfo->pOutputData; + + pRosAdapterInfo->m_version = ROSD_VERSION; + pRosAdapterInfo->m_wddmVersion = m_WDDMVersion; + + // Software APCI device only claims an interrupt resource + pRosAdapterInfo->m_isSoftwareDevice = (m_flags.m_isVC4 != 1); + + RtlCopyMemory( + pRosAdapterInfo->m_deviceId, + m_deviceId, + m_deviceIdLength); + } + break; + + case DXGKQAITYPE_DRIVERCAPS: + { + if (pQueryAdapterInfo->OutputDataSize < sizeof(DXGK_DRIVERCAPS)) + { + ROS_LOG_ASSERTION( + "Output buffer is too small. (pQueryAdapterInfo->OutputDataSize=%d, sizeof(DXGK_DRIVERCAPS)=%d)", + pQueryAdapterInfo->OutputDataSize, + sizeof(DXGK_DRIVERCAPS)); + return STATUS_BUFFER_TOO_SMALL; + } + + DXGK_DRIVERCAPS *pDriverCaps = (DXGK_DRIVERCAPS *)pQueryAdapterInfo->pOutputData; + + // + // HighestAcceptableAddress + // + pDriverCaps->HighestAcceptableAddress.QuadPart = -1; + + // + // TODO[bhouse] MaxAllocationListSlotId + // + + // + // TODO[bhouse] ApertureSegmentCommitLimit + // + + // + // TODO[bhouse] MaxPointerWidth + // + + // + // TODO[bhouse] MaxPointerHeight + // + + // + // TODO[bhouse] PointerCaps + // + + // + // TODO[bhouse] InterruptMessageNumber + // + + // + // TODO[bhouse] NumberOfSwizzlingRanges + // + + // + // TODO[bhouse] MaxOverlays + // + + // + // TODO[bhouse] GammarRampCaps + // + + // + // TODO[bhouse] PresentationCaps + // + + pDriverCaps->PresentationCaps.SupportKernelModeCommandBuffer = FALSE; + pDriverCaps->PresentationCaps.SupportSoftwareDeviceBitmaps = TRUE; + + // + // Cap used for DWM off case, screen to screen blt is slow + // + pDriverCaps->PresentationCaps.NoScreenToScreenBlt = TRUE; + pDriverCaps->PresentationCaps.NoOverlapScreenBlt = TRUE; + + // + // Allow 16Kx16K (2 << (11 + 3)) texture(redirection device bitmap) + // + pDriverCaps->PresentationCaps.MaxTextureWidthShift = 3; + pDriverCaps->PresentationCaps.MaxTextureHeightShift = 3; + + // + // Use SW flip queue for flip with interval of 1 or more + // - we must NOT generate a DMA buffer in DxgkDdiPresent. That is, + // we must set the DXGKARG_PRESENT.pDmaBuffer output parameter + // to NULL. + // - DxgkDdiSetVidPnSourceAddress will be called at DIRQL + // + pDriverCaps->FlipCaps.FlipOnVSyncMmIo = TRUE; + + if (!RosKmdGlobal::IsRenderOnly()) + { + // + // The hardware can store at most one pending flip operation. + // + pDriverCaps->MaxQueuedFlipOnVSync = 1; + + // + // FlipOnVSyncWithNoWait - we don't have to wait for the next VSync + // to program in the new source address. We can program in the new + // source address and return immediately, and it will take + // effect at the next vsync. + // + pDriverCaps->FlipCaps.FlipOnVSyncWithNoWait = TRUE; + + // + // We do not support the scheduling of a flip command to take effect + // after two, three, or four vertical syncs. + // + pDriverCaps->FlipCaps.FlipInterval = FALSE; + + // + // The address we program into hardware does not take effect until + // the next vsync. + // + pDriverCaps->FlipCaps.FlipImmediateMmIo = FALSE; + + // + // WDDM 1.3 and later drivers must set this to TRUE. + // In an independent flip, the DWM user-mode present call is skipped + // and DxgkDdiPresent and DxgkDdiSetVidPnSourceAddress are called. + // + pDriverCaps->FlipCaps.FlipIndependent = TRUE; + + // + // TODO[jordanrh] VSyncPowerSaveAware + // https://msdn.microsoft.com/en-us/library/windows/hardware/ff569520(v=vs.85).aspx + // + } + + // + // TODO[bhouse] SchedulingCaps + // + +#if 1 + pDriverCaps->SchedulingCaps.MultiEngineAware = 1; +#endif + + // + // Set scheduling caps to indicate support for cancelling DMA buffer + // +#if 1 + pDriverCaps->SchedulingCaps.CancelCommandAware = 1; +#endif + + // + // Set scheduling caps to indicate driver is preemption aware + // +#if 1 + pDriverCaps->SchedulingCaps.PreemptionAware = 1; +#endif + + // + // TODO[bhouse] MemoryManagementCaps + // +#if 1 + pDriverCaps->MemoryManagementCaps.CrossAdapterResource = 1; +#endif + + // + // TODO[bhouse] GpuEngineTopology + // + + pDriverCaps->GpuEngineTopology.NbAsymetricProcessingNodes = m_NumNodes; + + // + // TODO[bhouse] WDDMVersion + // Documentation states that we should not set this value if WDDM 1.3 + // + pDriverCaps->WDDMVersion = m_WDDMVersion; + + // + // TODO[bhouse] VirtualAddressCaps + // + + // + // TODO[bhouse] DmaBufferCaps + // + + // + // TODO[bhouse] PreemptionCaps + // +#if 1 + pDriverCaps->PreemptionCaps.GraphicsPreemptionGranularity = D3DKMDT_GRAPHICS_PREEMPTION_PRIMITIVE_BOUNDARY; + pDriverCaps->PreemptionCaps.ComputePreemptionGranularity = D3DKMDT_COMPUTE_PREEMPTION_DISPATCH_BOUNDARY; +#endif + + // + // Must support DxgkDdiStopDeviceAndReleasePostDisplayOwnership + // + pDriverCaps->SupportNonVGA = TRUE; + + // + // Must support updating path rotation in DxgkDdiUpdateActiveVidPnPresentPath + // + pDriverCaps->SupportSmoothRotation = TRUE; + + // + // TODO[bhouse] SupportPerEngineTDR + // +#if 1 + pDriverCaps->SupportPerEngineTDR = 1; +#endif + + // + // SupportDirectFlip + // - must not allow video memory to be flipped to an incompatible + // allocation in DxgkDdiSetVidPnSourceAddress + // - the user mode driver must validate Direct Flip resources before + // the DWM uses them + // + pDriverCaps->SupportDirectFlip = 1; + + // + // TODO[bhouse] SupportMultiPlaneOverlay + // + + // + // Support SupportRuntimePowerManagement + // TODO[jordanrh] setting this to true causes constant power state transitions + // + pDriverCaps->SupportRuntimePowerManagement = FALSE; + + // + // TODO[bhouse] SupportSurpriseRemovalInHibernation + // + + // + // TODO[bhouse] HybridDiscrete + // + + // + // TODO[bhouse] MaxOverlayPlanes + // + + } + break; + + case DXGKQAITYPE_QUERYSEGMENT3: + { + if (pQueryAdapterInfo->OutputDataSize < sizeof(DXGK_QUERYSEGMENTOUT3)) + { + ROS_LOG_ASSERTION( + "Output buffer is too small. (pQueryAdapterInfo->OutputDataSize=%d, sizeof(DXGK_QUERYSEGMENTOUT3)=%d)", + pQueryAdapterInfo->OutputDataSize, + sizeof(DXGK_QUERYSEGMENTOUT3)); + return STATUS_BUFFER_TOO_SMALL; + } + + DXGK_QUERYSEGMENTOUT3 *pSegmentInfo = (DXGK_QUERYSEGMENTOUT3*)pQueryAdapterInfo->pOutputData; + + if (!pSegmentInfo[0].pSegmentDescriptor) + { + pSegmentInfo->NbSegment = 2; + } + else + { + DXGK_SEGMENTDESCRIPTOR3 *pSegmentDesc = pSegmentInfo->pSegmentDescriptor; + + // + // Private data size should be the maximum of UMD and KMD and the same size must + // be reported in DxgkDdiCreateContext for paging engine + // + pSegmentInfo->PagingBufferPrivateDataSize = sizeof(ROSUMDDMAPRIVATEDATA2); + + pSegmentInfo->PagingBufferSegmentId = ROSD_SEGMENT_APERTURE; + pSegmentInfo->PagingBufferSize = PAGE_SIZE; + + // + // Fill out aperture segment descriptor + // + memset(&pSegmentDesc[0], 0, sizeof(pSegmentDesc[0])); + + pSegmentDesc[0].Flags.Aperture = TRUE; + + // + // TODO[bhouse] What does marking it CacheCoherent mean? What are the side effects? + // What happens if we don't mark CacheCoherent? + // + pSegmentDesc[0].Flags.CacheCoherent = TRUE; + + // + // TODO[bhouse] BaseAddress should never be used. Do we need to set this still? + // + + pSegmentDesc[0].BaseAddress.QuadPart = ROSD_SEGMENT_APERTURE_BASE_ADDRESS; + + // + // Our fake apperture is not really visible and doesn't need to be. We + // still need to lie that it is visible reporting a bad physical address + // that will never be used. This is a legacy requirement of the DX stack. + // + + pSegmentDesc[0].CpuTranslatedAddress.QuadPart = 0xFFFFFFFE00000000; + pSegmentDesc[0].Flags.CpuVisible = TRUE; + + pSegmentDesc[0].Size = kApertureSegmentSize; + pSegmentDesc[0].CommitLimit = kApertureSegmentSize; + + // + // Setup local video memory segment + // + + memset(&pSegmentDesc[1], 0, sizeof(pSegmentDesc[1])); + + pSegmentDesc[1].BaseAddress.QuadPart = 0LL; // Gpu base physical address + pSegmentDesc[1].Flags.CpuVisible = true; + pSegmentDesc[1].Flags.CacheCoherent = true; + pSegmentDesc[1].Flags.DirectFlip = true; + pSegmentDesc[1].CpuTranslatedAddress = RosKmdGlobal::s_videoMemoryPhysicalAddress; // cpu base physical address + pSegmentDesc[1].Size = m_localVidMemSegmentSize; + + } + } + break; + + case DXGKQAITYPE_NUMPOWERCOMPONENTS: + { + if (pQueryAdapterInfo->OutputDataSize != sizeof(UINT)) + { + ROS_LOG_ASSERTION( + "Output buffer is unexpected size. (pQueryAdapterInfo->OutputDataSize=%d, sizeof(UINT)=%d)", + pQueryAdapterInfo->OutputDataSize, + sizeof(UINT)); + return STATUS_INVALID_PARAMETER; + } + + // + // Support only one 3D engine(s). + // + *(static_cast(pQueryAdapterInfo->pOutputData)) = GetNumPowerComponents(); + } + break; + + case DXGKQAITYPE_POWERCOMPONENTINFO: + { + if (pQueryAdapterInfo->InputDataSize != sizeof(UINT)) + { + ROS_LOG_ASSERTION( + "Input buffer is not of the expected size. (pQueryAdapterInfo->InputDataSize=%d, sizeof(UINT)=%d)", + pQueryAdapterInfo->InputDataSize, + sizeof(UINT)); + return STATUS_INVALID_PARAMETER; + } + + if (pQueryAdapterInfo->OutputDataSize < sizeof(DXGK_POWER_RUNTIME_COMPONENT)) + { + ROS_LOG_ASSERTION( + "Output buffer is too small. (pQueryAdapterInfo->OutputDataSize=%d, sizeof(DXGK_POWER_RUNTIME_COMPONENT)=%d)", + pQueryAdapterInfo->OutputDataSize, + sizeof(DXGK_POWER_RUNTIME_COMPONENT)); + return STATUS_BUFFER_TOO_SMALL; + } + + ULONG ComponentIndex = *(reinterpret_cast(pQueryAdapterInfo->pInputData)); + DXGK_POWER_RUNTIME_COMPONENT* pPowerComponent = reinterpret_cast(pQueryAdapterInfo->pOutputData); + + NTSTATUS status = GetPowerComponentInfo(ComponentIndex, pPowerComponent); + if (!NT_SUCCESS(status)) + { + ROS_LOG_ERROR( + "GetPowerComponentInfo(...) failed. (status=%!STATUS!, ComponentIndex=%d, pPowerComponent=0x%p)", + status, + ComponentIndex, + pPowerComponent); + return status; + } + } + break; + + case DXGKQAITYPE_HISTORYBUFFERPRECISION: + { + UINT NumStructures = pQueryAdapterInfo->OutputDataSize / sizeof(DXGKARG_HISTORYBUFFERPRECISION); + + for (UINT i = 0; i < NumStructures; i++) + { + DXGKARG_HISTORYBUFFERPRECISION *pHistoryBufferPrecision = ((DXGKARG_HISTORYBUFFERPRECISION *)pQueryAdapterInfo->pOutputData) + i; + + pHistoryBufferPrecision->PrecisionBits = 64; + } + + } + break; + + default: + ROS_LOG_WARNING( + "Unsupported query type. (pQueryAdapterInfo->Type=%d, pQueryAdapterInfo=0x%p)", + pQueryAdapterInfo->Type, + pQueryAdapterInfo); + return STATUS_NOT_SUPPORTED; + } + + return STATUS_SUCCESS; +} + +NTSTATUS +RosKmAdapter::DescribeAllocation( + INOUT_PDXGKARG_DESCRIBEALLOCATION pDescribeAllocation) +{ + RosKmdAllocation *pAllocation = (RosKmdAllocation *)pDescribeAllocation->hAllocation; + + pDescribeAllocation->Width = pAllocation->m_mip0Info.TexelWidth; + pDescribeAllocation->Height = pAllocation->m_mip0Info.TexelHeight; + pDescribeAllocation->Format = TranslateDxgiFormat(pAllocation->m_format); + + pDescribeAllocation->MultisampleMethod.NumSamples = pAllocation->m_sampleDesc.Count; + pDescribeAllocation->MultisampleMethod.NumQualityLevels = pAllocation->m_sampleDesc.Quality; + + pDescribeAllocation->RefreshRate.Numerator = pAllocation->m_primaryDesc.ModeDesc.RefreshRate.Numerator; + pDescribeAllocation->RefreshRate.Denominator = pAllocation->m_primaryDesc.ModeDesc.RefreshRate.Denominator; + + return STATUS_SUCCESS; + +} + +NTSTATUS +RosKmAdapter::GetNodeMetadata( + UINT NodeOrdinal, + OUT_PDXGKARG_GETNODEMETADATA pGetNodeMetadata + ) +{ + RtlZeroMemory(pGetNodeMetadata, sizeof(*pGetNodeMetadata)); + + pGetNodeMetadata->EngineType = DXGK_ENGINE_TYPE_3D; + + RtlStringCbPrintfW(pGetNodeMetadata->FriendlyName, + sizeof(pGetNodeMetadata->FriendlyName), + L"3DNode%02X", + NodeOrdinal); + + + return STATUS_SUCCESS; +} + + +NTSTATUS +RosKmAdapter::SubmitCommandVirtual( + IN_CONST_PDXGKARG_SUBMITCOMMANDVIRTUAL /*pSubmitCommandVirtual*/) +{ + ROS_LOG_ASSERTION("Not implemented"); + return STATUS_NOT_IMPLEMENTED; +} + +NTSTATUS +RosKmAdapter::PreemptCommand( + IN_CONST_PDXGKARG_PREEMPTCOMMAND /*pPreemptCommand*/) +{ + ROS_LOG_WARNING("Not implemented"); + return STATUS_SUCCESS; +} + +NTSTATUS +RosKmAdapter::RestartFromTimeout(void) +{ + ROS_LOG_ASSERTION("Not implemented"); + return STATUS_NOT_IMPLEMENTED; +} + +NTSTATUS +RosKmAdapter::CancelCommand( + IN_CONST_PDXGKARG_CANCELCOMMAND /*pCancelCommand*/) +{ + ROS_LOG_ASSERTION("Not implemented"); + return STATUS_NOT_IMPLEMENTED; +} + +NTSTATUS +RosKmAdapter::QueryCurrentFence( + INOUT_PDXGKARG_QUERYCURRENTFENCE pCurrentFence) +{ + ROS_LOG_WARNING("Not implemented"); + + NT_ASSERT(pCurrentFence->NodeOrdinal == 0); + NT_ASSERT(pCurrentFence->EngineOrdinal == 0); + + pCurrentFence->CurrentFence = 0; + return STATUS_SUCCESS; +} + +NTSTATUS +RosKmAdapter::ResetEngine( + INOUT_PDXGKARG_RESETENGINE /*pResetEngine*/) +{ + ROS_LOG_WARNING("Not implemented"); + return STATUS_SUCCESS; +} + +NTSTATUS +RosKmAdapter::CollectDbgInfo( + IN_CONST_PDXGKARG_COLLECTDBGINFO /*pCollectDbgInfo*/) +{ + ROS_LOG_WARNING("Not implemented"); + return STATUS_SUCCESS; +} + +NTSTATUS +RosKmAdapter::CreateProcess( + IN DXGKARG_CREATEPROCESS* /*pArgs*/) +{ + // pArgs->hKmdProcess = 0; + ROS_LOG_ASSERTION("Not implemented"); + return STATUS_NOT_IMPLEMENTED; +} + +NTSTATUS +RosKmAdapter::DestroyProcess( + IN HANDLE /*KmdProcessHandle*/) +{ + ROS_LOG_ASSERTION("Not implemented"); + return STATUS_NOT_IMPLEMENTED; +} + +void +RosKmAdapter::SetStablePowerState( + IN_CONST_PDXGKARG_SETSTABLEPOWERSTATE pArgs) +{ + UNREFERENCED_PARAMETER(pArgs); + ROS_LOG_ASSERTION("Not implemented"); +} + +NTSTATUS +RosKmAdapter::CalibrateGpuClock( + IN UINT32 /*NodeOrdinal*/, + IN UINT32 /*EngineOrdinal*/, + OUT_PDXGKARG_CALIBRATEGPUCLOCK /*pClockCalibration*/ + ) +{ + ROS_LOG_ASSERTION("Not implemented"); + return STATUS_NOT_IMPLEMENTED; +} + +NTSTATUS +RosKmAdapter::Escape( + IN_CONST_PDXGKARG_ESCAPE pEscape) +{ + NTSTATUS Status; + + if (pEscape->PrivateDriverDataSize < sizeof(UINT)) + { + ROS_LOG_ERROR( + "PrivateDriverDataSize is too small. (pEscape->PrivateDriverDataSize=%d, sizeof(UINT)=%d)", + pEscape->PrivateDriverDataSize, + sizeof(UINT)); + return STATUS_BUFFER_TOO_SMALL; + } + + UINT EscapeId = *((UINT *)pEscape->pPrivateDriverData); + +#pragma warning( disable : 4065 ) + switch (EscapeId) + { + + default: + + NT_ASSERT(false); + Status = STATUS_NOT_SUPPORTED; + break; + } + + ROS_LOG_ASSERTION("Not implemented"); + return STATUS_NOT_IMPLEMENTED; +} + +NTSTATUS +RosKmAdapter::ResetFromTimeout(void) +{ + ROS_LOG_ASSERTION("Not implemented"); + return STATUS_NOT_IMPLEMENTED; +} + +NTSTATUS +RosKmAdapter::QueryChildRelations( + INOUT_PDXGK_CHILD_DESCRIPTOR ChildRelations, + IN_ULONG ChildRelationsSize) +{ + if (RosKmdGlobal::IsRenderOnly()) + { + ROS_LOG_ASSERTION("QueryChildRelations() is not supported by render-only driver."); + return STATUS_NOT_IMPLEMENTED; + } + + return m_display.QueryChildRelations(ChildRelations, ChildRelationsSize); +} + +NTSTATUS +RosKmAdapter::QueryChildStatus( + IN_PDXGK_CHILD_STATUS ChildStatus, + IN_BOOLEAN NonDestructiveOnly) +{ + if (RosKmdGlobal::IsRenderOnly()) + { + ROS_LOG_ASSERTION("QueryChildStatus() is not supported by render-only driver."); + return STATUS_NOT_IMPLEMENTED; + } + + return m_display.QueryChildStatus(ChildStatus, NonDestructiveOnly); +} + +NTSTATUS +RosKmAdapter::QueryDeviceDescriptor( + IN_ULONG ChildUid, + INOUT_PDXGK_DEVICE_DESCRIPTOR pDeviceDescriptor) +{ + if (RosKmdGlobal::IsRenderOnly()) + { + ROS_LOG_ASSERTION("QueryChildStatus() is not supported by render-only driver."); + return STATUS_NOT_IMPLEMENTED; + } + + return m_display.QueryDeviceDescriptor(ChildUid, pDeviceDescriptor); +} + +NTSTATUS +RosKmAdapter::NotifyAcpiEvent( + IN_DXGK_EVENT_TYPE EventType, + IN_ULONG Event, + IN_PVOID Argument, + OUT_PULONG AcpiFlags) +{ + EventType; + Event; + Argument; + AcpiFlags; + + ROS_LOG_ASSERTION("Not implemented"); + return STATUS_NOT_IMPLEMENTED; +} + +void +RosKmAdapter::ResetDevice(void) +{ + // Do nothing + ROS_LOG_ASSERTION("Not implemented"); +} + +void +RosKmAdapter::PatchDmaBuffer( + ROSDMABUFINFO* pDmaBufInfo, + CONST DXGK_ALLOCATIONLIST* pAllocationList, + UINT allocationListSize, + CONST D3DDDI_PATCHLOCATIONLIST* pPatchLocationList, + UINT patchAllocationList) +{ + PBYTE pDmaBuf = (PBYTE)pDmaBufInfo->m_pDmaBuffer; + + for (UINT i = 0; i < patchAllocationList; i++) + { + auto patch = &pPatchLocationList[i]; + + allocationListSize; + NT_ASSERT(patch->AllocationIndex < allocationListSize); + + auto allocation = &pAllocationList[patch->AllocationIndex]; + + RosKmdDeviceAllocation * pRosKmdDeviceAllocation = (RosKmdDeviceAllocation *)allocation->hDeviceSpecificAllocation; + + if (allocation->SegmentId != 0) + { + DbgPrintEx(DPFLTR_IHVVIDEO_ID, DPFLTR_TRACE_LEVEL, "Patch RosKmdDeviceAllocation %lx at %lx\n", pRosKmdDeviceAllocation, allocation->PhysicalAddress); + DbgPrintEx(DPFLTR_IHVVIDEO_ID, DPFLTR_TRACE_LEVEL, "Patch buffer offset %lx allocation offset %lx\n", patch->PatchOffset, patch->AllocationOffset); + + // Patch in dma buffer + NT_ASSERT(allocation->SegmentId == ROSD_SEGMENT_VIDEO_MEMORY); + if (pDmaBufInfo->m_DmaBufState.m_bSwCommandBuffer) + { + PHYSICAL_ADDRESS allocAddress; + + allocAddress.QuadPart = allocation->PhysicalAddress.QuadPart + (LONGLONG)patch->AllocationOffset; + *((PHYSICAL_ADDRESS *)(pDmaBuf + patch->PatchOffset)) = allocAddress; + } + else + { + // Patch HW command buffer +#if VC4 + UINT physicalAddress = + RosKmdGlobal::s_videoMemoryPhysicalAddress.LowPart + + allocation->PhysicalAddress.LowPart + + patch->AllocationOffset; + + switch (patch->SlotId) + { + case VC4_SLOT_RT_BINNING_CONFIG: + pDmaBufInfo->m_RenderTargetPhysicalAddress = physicalAddress; + pDmaBufInfo->m_RenderTargetVirtualAddress = + static_cast(RosKmdGlobal::s_pVideoMemory) + + allocation->PhysicalAddress.LowPart + + patch->AllocationOffset; + break; + case VC4_SLOT_TILE_ALLOCATION_MEMORY: + *((UINT *)(pDmaBuf + patch->PatchOffset)) = m_tileAllocationMemoryPhysicalAddress + m_busAddressOffset; + break; + case VC4_SLOT_TILE_STATE_DATA_ARRAY: + *((UINT *)(pDmaBuf + patch->PatchOffset)) = m_tileStateDataArrayPhysicalAddress + m_busAddressOffset; + break; + case VC4_SLOT_NV_SHADER_STATE: + case VC4_SLOT_BRANCH: + case VC4_SLOT_GL_SHADER_STATE: + case VC4_SLOT_FS_UNIFORM_ADDRESS: + case VC4_SLOT_VS_UNIFORM_ADDRESS: + case VC4_SLOT_CS_UNIFORM_ADDRESS: + // When PrePatch happens in DdiRender, DMA buffer physical + // address is not available, so DMA buffer self-reference + // patches are handled in SubmitCommand + break; + default: + *((UINT *)(pDmaBuf + patch->PatchOffset)) = physicalAddress + m_busAddressOffset; + } +#endif + } + } + } +} + +// +// TODO[indyz]: Add proper validation for DMA buffer +// +bool +RosKmAdapter::ValidateDmaBuffer( + ROSDMABUFINFO* pDmaBufInfo, + CONST DXGK_ALLOCATIONLIST* pAllocationList, + UINT allocationListSize, + CONST D3DDDI_PATCHLOCATIONLIST* pPatchLocationList, + UINT patchAllocationList) +{ + PBYTE pDmaBuf = (PBYTE)pDmaBufInfo->m_pDmaBuffer; + bool bValidateDmaBuffer = true; + ROSDMABUFSTATE* pDmaBufState = &pDmaBufInfo->m_DmaBufState; + + pDmaBuf; + + if (! pDmaBufInfo->m_DmaBufState.m_bSwCommandBuffer) + { + for (UINT i = 0; i < patchAllocationList; i++) + { + auto patch = &pPatchLocationList[i]; + + allocationListSize; + NT_ASSERT(patch->AllocationIndex < allocationListSize); + + auto allocation = &pAllocationList[patch->AllocationIndex]; + + RosKmdDeviceAllocation * pRosKmdDeviceAllocation = (RosKmdDeviceAllocation *)allocation->hDeviceSpecificAllocation; + +#if VC4 + + switch (patch->SlotId) + { + case VC4_SLOT_TILE_ALLOCATION_MEMORY: + if (pDmaBufState->m_bTileAllocMemRef) + { + return false; // Allow one per DMA buffer + } + else + { + pDmaBufState->m_bTileAllocMemRef = 1; + } + break; + case VC4_SLOT_TILE_STATE_DATA_ARRAY: + if (pDmaBufState->m_bTileStateDataRef) + { + return false; // Allow one per DMA buffer + } + else + { + pDmaBufState->m_bTileStateDataRef = 1; + } + break; + case VC4_SLOT_RT_BINNING_CONFIG: + if (pDmaBufState->m_bRenderTargetRef) + { + return false; // Allow one per DMA buffer + } + else + { + pDmaBufInfo->m_pRenderTarget = pRosKmdDeviceAllocation->m_pRosKmdAllocation; + pDmaBufState->m_bRenderTargetRef = 1; + } + break; + case VC4_SLOT_NV_SHADER_STATE: + case VC4_SLOT_BRANCH: + case VC4_SLOT_GL_SHADER_STATE: + case VC4_SLOT_FS_UNIFORM_ADDRESS: + case VC4_SLOT_VS_UNIFORM_ADDRESS: + case VC4_SLOT_CS_UNIFORM_ADDRESS: + if (pDmaBufState->m_NumDmaBufSelfRef == VC4_MAX_DMA_BUFFER_SELF_REF) + { + return false; // Allow up to VC4_MAX_DMA_BUFFER_SELF_REF + } + else + { + pDmaBufInfo->m_DmaBufSelfRef[pDmaBufState->m_NumDmaBufSelfRef] = *patch; + pDmaBufState->m_NumDmaBufSelfRef++; + } + break; + default: + break; + } + +#endif + } + + if ((0 == pDmaBufState->m_bRenderTargetRef) || + (0 == pDmaBufState->m_bTileAllocMemRef) || + (0 == pDmaBufState->m_bTileStateDataRef)) + { + bValidateDmaBuffer = false; + } + } + + return bValidateDmaBuffer; +} + +void +RosKmAdapter::QueueDmaBuffer( + IN_CONST_PDXGKARG_SUBMITCOMMAND pSubmitCommand) +{ + ROSDMABUFINFO * pDmaBufInfo = (ROSDMABUFINFO *)pSubmitCommand->pDmaBufferPrivateData; + KIRQL OldIrql; + ROSDMABUFSUBMISSION * pDmaBufSubmission; + + KeAcquireSpinLock(&m_dmaBufQueueLock, &OldIrql); + + // + // Combination indicating preparation error, thus the DMA buffer should be discarded + // + if ((pSubmitCommand->DmaBufferPhysicalAddress.QuadPart == 0) && + (pSubmitCommand->DmaBufferSubmissionStartOffset == 0) && + (pSubmitCommand->DmaBufferSubmissionEndOffset == 0)) + { + m_ErrorHit.m_PreparationError = 1; + } + + if (!pDmaBufInfo->m_DmaBufState.m_bSubmittedOnce) + { + pDmaBufInfo->m_DmaBufState.m_bSubmittedOnce = 1; + } + + NT_ASSERT(!IsListEmpty(&m_dmaBufSubmissionFree)); + + pDmaBufSubmission = CONTAINING_RECORD(RemoveHeadList(&m_dmaBufSubmissionFree), ROSDMABUFSUBMISSION, m_QueueEntry); + + pDmaBufSubmission->m_pDmaBufInfo = pDmaBufInfo; + + pDmaBufSubmission->m_StartOffset = pSubmitCommand->DmaBufferSubmissionStartOffset; + pDmaBufSubmission->m_EndOffset = pSubmitCommand->DmaBufferSubmissionEndOffset; + pDmaBufSubmission->m_SubmissionFenceId = pSubmitCommand->SubmissionFenceId; + + InsertTailList(&m_dmaBufQueue, &pDmaBufSubmission->m_QueueEntry); + + KeReleaseSpinLock(&m_dmaBufQueueLock, OldIrql); +} + +void +RosKmAdapter::HwDmaBufCompletionDpcRoutine( + KDPC *pDPC, + PVOID deferredContext, + PVOID systemArgument1, + PVOID systemArgument2) +{ + RosKmAdapter *pRosKmAdapter = RosKmAdapter::Cast(deferredContext); + + UNREFERENCED_PARAMETER(pDPC); + UNREFERENCED_PARAMETER(systemArgument1); + UNREFERENCED_PARAMETER(systemArgument2); + + // Signal to the worker thread that a HW DMA buffer has completed + KeSetEvent(&pRosKmAdapter->m_hwDmaBufCompletionEvent, 0, FALSE); +} + +ROS_NONPAGED_SEGMENT_BEGIN; //================================================ + +_Use_decl_annotations_ +NTSTATUS RosKmAdapter::SetVidPnSourceAddress ( + const DXGKARG_SETVIDPNSOURCEADDRESS* SetVidPnSourceAddressPtr + ) +{ + NT_ASSERT(!RosKmdGlobal::IsRenderOnly()); + return m_display.SetVidPnSourceAddress(SetVidPnSourceAddressPtr); +} + +ROS_NONPAGED_SEGMENT_END; //================================================== +ROS_PAGED_SEGMENT_BEGIN; //=================================================== + +_Use_decl_annotations_ +NTSTATUS RosKmAdapter::QueryInterface (QUERY_INTERFACE* Args) +{ + ROS_LOG_WARNING( + "Received QueryInterface for unsupported interface. (InterfaceType=%!GUID!)", + Args->InterfaceType); + return STATUS_NOT_SUPPORTED; +} + +_Use_decl_annotations_ +NTSTATUS RosKmAdapter::GetStandardAllocationDriverData ( + DXGKARG_GETSTANDARDALLOCATIONDRIVERDATA* Args + ) +{ + PAGED_CODE(); + ROS_ASSERT_MAX_IRQL(PASSIVE_LEVEL); + + // + // ResourcePrivateDriverDataSize gets passed to CreateAllocation as + // PrivateDriverDataSize. + // AllocationPrivateDriverDataSize get passed to CreateAllocation as + // pAllocationInfo->PrivateDriverDataSize. + // + + if (!Args->pResourcePrivateDriverData && !Args->pResourcePrivateDriverData) + { + Args->ResourcePrivateDriverDataSize = sizeof(RosAllocationGroupExchange); + Args->AllocationPrivateDriverDataSize = sizeof(RosAllocationExchange); + return STATUS_SUCCESS; + } + + // we expect them to both be null or both be valid + NT_ASSERT(Args->pResourcePrivateDriverData && Args->pResourcePrivateDriverData); + NT_ASSERT( + Args->ResourcePrivateDriverDataSize == + sizeof(RosAllocationGroupExchange)); + + NT_ASSERT( + Args->AllocationPrivateDriverDataSize == + sizeof(RosAllocationExchange)); + + new (Args->pResourcePrivateDriverData) RosAllocationGroupExchange(); + auto allocParams = new (Args->pAllocationPrivateDriverData) RosAllocationExchange(); + + switch (Args->StandardAllocationType) + { + case D3DKMDT_STANDARDALLOCATION_SHAREDPRIMARYSURFACE: + { + const D3DKMDT_SHAREDPRIMARYSURFACEDATA* surfData = + Args->pCreateSharedPrimarySurfaceData; + + ROS_LOG_TRACE( + "Preparing private allocation data for SHAREDPRIMARYSURFACEDATA. (Width=%d, Height=%d, Format=%d, RefreshRate=%d/%d, VidPnSourceId=%d)", + surfData->Width, + surfData->Height, + surfData->Format, + surfData->RefreshRate.Numerator, + surfData->RefreshRate.Denominator, + surfData->VidPnSourceId); + + allocParams->m_resourceDimension = D3D10DDIRESOURCE_TEXTURE2D; + allocParams->m_mip0Info.TexelWidth = surfData->Width; + allocParams->m_mip0Info.TexelHeight = surfData->Height; + allocParams->m_mip0Info.TexelDepth = 1; + allocParams->m_mip0Info.PhysicalWidth = surfData->Width; + allocParams->m_mip0Info.PhysicalHeight = surfData->Height; + allocParams->m_mip0Info.PhysicalDepth = 1; + + allocParams->m_usage = D3D10_DDI_USAGE_IMMUTABLE; + + // We must ensure that the D3D10_DDI_BIND_PRESENT is set so that + // CreateAllocation() creates an allocation that is suitable + // for the primary, which must be flippable. + // The primary cannot be cached. + allocParams->m_bindFlags = D3D10_DDI_BIND_RENDER_TARGET | D3D10_DDI_BIND_PRESENT; + + allocParams->m_mapFlags = 0; + + // The shared primary allocation is shared by definition + allocParams->m_miscFlags = D3D10_DDI_RESOURCE_MISC_SHARED; + + allocParams->m_format = DxgiFormatFromD3dDdiFormat(surfData->Format); + allocParams->m_sampleDesc.Count = 1; + allocParams->m_sampleDesc.Quality = 0; + allocParams->m_mipLevels = 1; + allocParams->m_arraySize = 1; + allocParams->m_isPrimary = true; + allocParams->m_primaryDesc.Flags = 0; + allocParams->m_primaryDesc.VidPnSourceId = surfData->VidPnSourceId; + allocParams->m_primaryDesc.ModeDesc.Width = surfData->Width; + allocParams->m_primaryDesc.ModeDesc.Height = surfData->Height; + allocParams->m_primaryDesc.ModeDesc.Format = DxgiFormatFromD3dDdiFormat(surfData->Format); + allocParams->m_primaryDesc.ModeDesc.RefreshRate.Numerator = surfData->RefreshRate.Numerator; + allocParams->m_primaryDesc.ModeDesc.RefreshRate.Denominator = surfData->RefreshRate.Denominator; + allocParams->m_primaryDesc.ModeDesc.ScanlineOrdering = DXGI_DDI_MODE_SCANLINE_ORDER_UNSPECIFIED; + allocParams->m_primaryDesc.ModeDesc.Rotation = DXGI_DDI_MODE_ROTATION_UNSPECIFIED; + allocParams->m_primaryDesc.ModeDesc.Scaling = DXGI_DDI_MODE_SCALING_UNSPECIFIED; + allocParams->m_primaryDesc.DriverFlags = 0; + + allocParams->m_hwLayout = RosHwLayout::Linear; + allocParams->m_hwWidthPixels = surfData->Width; + allocParams->m_hwHeightPixels = surfData->Height; + + NT_ASSERT(surfData->Format == D3DDDIFMT_A8R8G8B8); + allocParams->m_hwFormat = RosHwFormat::X8888; + allocParams->m_hwPitchBytes = surfData->Width * 4; + allocParams->m_hwSizeBytes = allocParams->m_hwPitchBytes * surfData->Height; + + return STATUS_SUCCESS; + } + case D3DKMDT_STANDARDALLOCATION_SHADOWSURFACE: + { + const D3DKMDT_SHADOWSURFACEDATA* surfData = Args->pCreateShadowSurfaceData; + ROS_LOG_TRACE( + "Preparing private allocation data for SHADOWSURFACE. (Width=%d, Height=%d, Format=%d)", + surfData->Width, + surfData->Height, + surfData->Format); + + allocParams->m_resourceDimension = D3D10DDIRESOURCE_TEXTURE2D; + allocParams->m_mip0Info.TexelWidth = surfData->Width; + allocParams->m_mip0Info.TexelHeight = surfData->Height; + allocParams->m_mip0Info.TexelDepth = 0; + allocParams->m_mip0Info.PhysicalWidth = surfData->Width; + allocParams->m_mip0Info.PhysicalHeight = surfData->Height; + allocParams->m_mip0Info.PhysicalDepth = 0; + allocParams->m_usage = D3D10_DDI_USAGE_DEFAULT; + + // The shadow allocation does not get flipped directly + static_assert( + !(D3D10_DDI_BIND_PIPELINE_MASK & D3D10_DDI_BIND_PRESENT), + "BIND_PRESENT must not be part of BIND_MASK"); + allocParams->m_bindFlags = D3D10_DDI_BIND_PIPELINE_MASK; + + allocParams->m_mapFlags = D3D10_DDI_MAP_READWRITE; + allocParams->m_miscFlags = D3D10_DDI_RESOURCE_MISC_SHARED; + + allocParams->m_format = DxgiFormatFromD3dDdiFormat(surfData->Format); + allocParams->m_sampleDesc.Count = 1; + allocParams->m_sampleDesc.Quality = 0; + allocParams->m_mipLevels = 1; + allocParams->m_arraySize = 1; + allocParams->m_isPrimary = true; + allocParams->m_primaryDesc.Flags = 0; + allocParams->m_primaryDesc.ModeDesc.Width = surfData->Width; + allocParams->m_primaryDesc.ModeDesc.Height = surfData->Height; + allocParams->m_primaryDesc.ModeDesc.Format = DxgiFormatFromD3dDdiFormat(surfData->Format); + allocParams->m_primaryDesc.DriverFlags = 0; + allocParams->m_hwLayout = RosHwLayout::Linear; + allocParams->m_hwWidthPixels = surfData->Width; + allocParams->m_hwHeightPixels = surfData->Height; + + NT_ASSERT(surfData->Format == D3DDDIFMT_A8R8G8B8); + allocParams->m_hwFormat = RosHwFormat::X8888; + allocParams->m_hwPitchBytes = surfData->Width * 4; + allocParams->m_hwSizeBytes = allocParams->m_hwPitchBytes * surfData->Height; + + Args->pCreateShadowSurfaceData->Pitch = allocParams->m_hwPitchBytes; + return STATUS_SUCCESS; + } + case D3DKMDT_STANDARDALLOCATION_STAGINGSURFACE: + { + const D3DKMDT_STAGINGSURFACEDATA* surfData = Args->pCreateStagingSurfaceData; + ROS_LOG_ASSERTION( + "STAGINGSURFACEDATA is not implemented. (Width=%d, Height=%d, Pitch=%d)", + surfData->Width, + surfData->Height, + surfData->Pitch); + return STATUS_NOT_IMPLEMENTED; + } + case D3DKMDT_STANDARDALLOCATION_GDISURFACE: + { + const D3DKMDT_GDISURFACEDATA* surfData = Args->pCreateGdiSurfaceData; + ROS_LOG_ASSERTION( + "GDISURFACEDATA is not implemented. We must return a nonzero Pitch if allocation is CPU visible. (Width=%d, Height=%d, Format=%d, Type=%d, Flags=0x%x, Pitch=%d)", + surfData->Width, + surfData->Height, + surfData->Format, + surfData->Type, + surfData->Flags.Value, + surfData->Pitch); + return STATUS_NOT_IMPLEMENTED; + } + default: + ROS_LOG_ASSERTION( + "Unknown standard allocation type. (StandardAllocationType=%d)", + Args->StandardAllocationType); + return STATUS_INVALID_PARAMETER; + } +} + +_Use_decl_annotations_ +NTSTATUS RosKmAdapter::SetPalette (const DXGKARG_SETPALETTE* /*SetPalettePtr*/) +{ + PAGED_CODE(); + ROS_ASSERT_MAX_IRQL(PASSIVE_LEVEL); + + ROS_LOG_ASSERTION("Not implemented."); + return STATUS_NOT_IMPLEMENTED; +} + +_Use_decl_annotations_ +NTSTATUS RosKmAdapter::SetPointerPosition ( + const DXGKARG_SETPOINTERPOSITION* SetPointerPositionPtr + ) +{ + PAGED_CODE(); + ROS_ASSERT_MAX_IRQL(PASSIVE_LEVEL); + + NT_ASSERT(!RosKmdGlobal::IsRenderOnly()); + return m_display.SetPointerPosition(SetPointerPositionPtr); +} + +_Use_decl_annotations_ +NTSTATUS RosKmAdapter::SetPointerShape ( + const DXGKARG_SETPOINTERSHAPE* SetPointerShapePtr + ) +{ + PAGED_CODE(); + ROS_ASSERT_MAX_IRQL(PASSIVE_LEVEL); + + NT_ASSERT(!RosKmdGlobal::IsRenderOnly()); + return m_display.SetPointerShape(SetPointerShapePtr); +} + +_Use_decl_annotations_ +NTSTATUS RosKmAdapter::IsSupportedVidPn ( + DXGKARG_ISSUPPORTEDVIDPN* IsSupportedVidPnPtr + ) +{ + PAGED_CODE(); + ROS_ASSERT_MAX_IRQL(PASSIVE_LEVEL); + + NT_ASSERT(!RosKmdGlobal::IsRenderOnly()); + return m_display.IsSupportedVidPn(IsSupportedVidPnPtr); +} + +_Use_decl_annotations_ +NTSTATUS RosKmAdapter::RecommendFunctionalVidPn ( + const DXGKARG_RECOMMENDFUNCTIONALVIDPN* const RecommendFunctionalVidPnPtr + ) +{ + PAGED_CODE(); + ROS_ASSERT_MAX_IRQL(PASSIVE_LEVEL); + + NT_ASSERT(!RosKmdGlobal::IsRenderOnly()); + return m_display.RecommendFunctionalVidPn(RecommendFunctionalVidPnPtr); +} + +_Use_decl_annotations_ +NTSTATUS RosKmAdapter::EnumVidPnCofuncModality ( + const DXGKARG_ENUMVIDPNCOFUNCMODALITY* const EnumCofuncModalityPtr + ) +{ + PAGED_CODE(); + ROS_ASSERT_MAX_IRQL(PASSIVE_LEVEL); + + NT_ASSERT(!RosKmdGlobal::IsRenderOnly()); + return m_display.EnumVidPnCofuncModality(EnumCofuncModalityPtr); +} + +_Use_decl_annotations_ +NTSTATUS RosKmAdapter::SetVidPnSourceVisibility ( + const DXGKARG_SETVIDPNSOURCEVISIBILITY* SetVidPnSourceVisibilityPtr + ) +{ + PAGED_CODE(); + ROS_ASSERT_MAX_IRQL(PASSIVE_LEVEL); + + NT_ASSERT(!RosKmdGlobal::IsRenderOnly()); + return m_display.SetVidPnSourceVisibility(SetVidPnSourceVisibilityPtr); +} + +_Use_decl_annotations_ +NTSTATUS RosKmAdapter::CommitVidPn ( + const DXGKARG_COMMITVIDPN* const CommitVidPnPtr + ) +{ + PAGED_CODE(); + ROS_ASSERT_MAX_IRQL(PASSIVE_LEVEL); + + NT_ASSERT(!RosKmdGlobal::IsRenderOnly()); + return m_display.CommitVidPn(CommitVidPnPtr); +} + +_Use_decl_annotations_ +NTSTATUS RosKmAdapter::UpdateActiveVidPnPresentPath ( + const DXGKARG_UPDATEACTIVEVIDPNPRESENTPATH* const UpdateActiveVidPnPresentPathPtr + ) +{ + PAGED_CODE(); + ROS_ASSERT_MAX_IRQL(PASSIVE_LEVEL); + + NT_ASSERT(!RosKmdGlobal::IsRenderOnly()); + return m_display.UpdateActiveVidPnPresentPath(UpdateActiveVidPnPresentPathPtr); +} + +_Use_decl_annotations_ +NTSTATUS RosKmAdapter::RecommendMonitorModes ( + const DXGKARG_RECOMMENDMONITORMODES* const RecommendMonitorModesPtr + ) +{ + PAGED_CODE(); + ROS_ASSERT_MAX_IRQL(PASSIVE_LEVEL); + + NT_ASSERT(!RosKmdGlobal::IsRenderOnly()); + return m_display.RecommendMonitorModes(RecommendMonitorModesPtr); +} + +_Use_decl_annotations_ +NTSTATUS RosKmAdapter::GetScanLine (DXGKARG_GETSCANLINE* /*GetScanLinePtr*/) +{ + PAGED_CODE(); + ROS_ASSERT_MAX_IRQL(PASSIVE_LEVEL); + + ROS_LOG_ASSERTION("Not implemented"); + return STATUS_NOT_IMPLEMENTED; +} + +_Use_decl_annotations_ +NTSTATUS RosKmAdapter::ControlInterrupt ( + const DXGK_INTERRUPT_TYPE InterruptType, + BOOLEAN EnableInterrupt + ) +{ + PAGED_CODE(); + ROS_ASSERT_MAX_IRQL(PASSIVE_LEVEL); + + NT_ASSERT(!RosKmdGlobal::IsRenderOnly()); + return m_display.ControlInterrupt(InterruptType, EnableInterrupt); +} + +_Use_decl_annotations_ +NTSTATUS RosKmAdapter::QueryVidPnHWCapability ( + DXGKARG_QUERYVIDPNHWCAPABILITY* VidPnHWCapsPtr + ) +{ + PAGED_CODE(); + ROS_ASSERT_MAX_IRQL(PASSIVE_LEVEL); + + NT_ASSERT(!RosKmdGlobal::IsRenderOnly()); + return m_display.QueryVidPnHWCapability(VidPnHWCapsPtr); +} + +_Use_decl_annotations_ +NTSTATUS RosKmAdapter::QueryDependentEngineGroup ( + DXGKARG_QUERYDEPENDENTENGINEGROUP* ArgsPtr + ) +{ + PAGED_CODE(); + ROS_ASSERT_MAX_IRQL(PASSIVE_LEVEL); + + NT_ASSERT(ArgsPtr->NodeOrdinal == 0); + NT_ASSERT(ArgsPtr->EngineOrdinal == 0); + + ArgsPtr->DependentNodeOrdinalMask = 0; + return STATUS_SUCCESS; +} + +_Use_decl_annotations_ +NTSTATUS RosKmAdapter::StopDeviceAndReleasePostDisplayOwnership ( + D3DDDI_VIDEO_PRESENT_TARGET_ID TargetId, + DXGK_DISPLAY_INFORMATION* DisplayInfoPtr + ) +{ + PAGED_CODE(); + ROS_ASSERT_MAX_IRQL(PASSIVE_LEVEL); + + NT_ASSERT(!RosKmdGlobal::IsRenderOnly()); + return m_display.StopDeviceAndReleasePostDisplayOwnership( + TargetId, + DisplayInfoPtr); +} + + +ROS_PAGED_SEGMENT_END; //===================================================== diff --git a/render-only-sample/roskmd/RosKmdAdapter.h b/render-only-sample/roskmd/RosKmdAdapter.h index 9b454e0..4ba2026 100644 --- a/render-only-sample/roskmd/RosKmdAdapter.h +++ b/render-only-sample/roskmd/RosKmdAdapter.h @@ -75,6 +75,7 @@ typedef struct _ROSDMABUFINFO RosKmdAllocation *m_pRenderTarget; UINT m_RenderTargetPhysicalAddress; + const void* m_RenderTargetVirtualAddress; D3DDDI_PATCHLOCATIONLIST m_DmaBufSelfRef[VC4_MAX_DMA_BUFFER_SELF_REF]; diff --git a/render-only-sample/roskmd/RosKmdLogging.h b/render-only-sample/roskmd/RosKmdLogging.h index 47a6c03..f15bd9a 100644 --- a/render-only-sample/roskmd/RosKmdLogging.h +++ b/render-only-sample/roskmd/RosKmdLogging.h @@ -1,5 +1,5 @@ -#ifndef _ROSLOGGING_H_ -#define _ROSLOGGING_H_ 1 +#ifndef _ROSKMDLOGGING_H_ +#define _ROSKMDLOGGING_H_ 1 // // Copyright (C) Microsoft. All rights reserved. @@ -10,23 +10,6 @@ // !rcdrkd.rcdrlogdump roskmd // -#ifdef __cplusplus -extern "C" { -#endif // __cplusplus - -// -// Defining control guids, including this is required to happen before -// including the tmh file (if the WppRecorder API is used) -// -#include - -// -// Debug/Bugcheck helpers used by tracing macros. -// NOTE: These are not intended to be called from anywhere else -// -extern int _RosLogBugcheck (ULONG Level); -extern int _RosLogDebug (ULONG Level); - // // Tracing GUID - B5B486C1-F57B-4993-8ED7-E3C2F5E4E65A // @@ -39,81 +22,6 @@ extern int _RosLogDebug (ULONG Level); WPP_DEFINE_BIT(ROS_TRACING_BUGCHECK) \ ) -// begin_wpp config -// -// FUNC ROS_LOG_CRITICAL_ERROR{LEVEL=TRACE_LEVEL_CRITICAL, FLAGS=ROS_TRACING_BUGCHECK}(MSG, ...); -// USEPREFIX (ROS_LOG_CRITICAL_ERROR, "%!STDPREFIX! [%s @ %u] CRITICAL ERROR:", __FILE__, __LINE__); -// -// FUNC ROS_LOG_ASSERTION{LEVEL=TRACE_LEVEL_ERROR, FLAGS=ROS_TRACING_DEBUG}(MSG, ...); -// USEPREFIX (ROS_LOG_ASSERTION, "%!STDPREFIX! [%s @ %u] ASSERTION :", __FILE__, __LINE__); -// -// FUNC ROS_LOG_ERROR{LEVEL=TRACE_LEVEL_ERROR, FLAGS=ROS_TRACING_DEFAULT}(MSG, ...); -// USEPREFIX (ROS_LOG_ERROR, "%!STDPREFIX! [%s @ %u] ERROR :", __FILE__, __LINE__); -// -// FUNC ROS_LOG_LOW_MEMORY{LEVEL=TRACE_LEVEL_ERROR, FLAGS=ROS_TRACING_DEFAULT}(MSG, ...); -// USEPREFIX (ROS_LOG_LOW_MEMORY, "%!STDPREFIX! [%s @ %u] LOW MEMORY :", __FILE__, __LINE__); -// -// FUNC ROS_LOG_WARNING{LEVEL=TRACE_LEVEL_WARNING, FLAGS=ROS_TRACING_DEFAULT}(MSG, ...); -// USEPREFIX (ROS_LOG_WARNING, "%!STDPREFIX! [%s @ %u] WARNING :", __FILE__, __LINE__); -// -// FUNC ROS_LOG_INFORMATION{LEVEL=TRACE_LEVEL_INFORMATION, FLAGS=ROS_TRACING_DEFAULT}(MSG, ...); -// USEPREFIX (ROS_LOG_INFORMATION, "%!STDPREFIX! [%s @ %u] INFO :", __FILE__, __LINE__); -// -// FUNC ROS_LOG_TRACE{LEVEL=TRACE_LEVEL_VERBOSE, FLAGS=ROS_TRACING_DEFAULT}(MSG, ...); -// USEPREFIX (ROS_LOG_TRACE, "%!STDPREFIX! [%s @ %u] TRACE :", __FILE__, __LINE__); -// -// FUNC ROS_TRACE_EVENTS(LEVEL, FLAGS, MSG, ...); -// USEPREFIX (ROS_TRACE_EVENTS, "%!STDPREFIX! [%s @ %u] TRACE :", __FILE__, __LINE__); -// -// FUNC ROS_CRITICAL_ASSERT{LEVEL=TRACE_LEVEL_CRITICAL, FLAGS=ROS_TRACING_BUGCHECK}(ROS_CRIT_ASSERT_EXP); -// USEPREFIX (ROS_CRITICAL_ASSERT, "%!STDPREFIX! [%s @ %u] CRITICAL ASSERTION :%s", __FILE__, __LINE__, #ROS_CRIT_ASSERT_EXP); -// -// FUNC ROS_ASSERT{LEVEL=TRACE_LEVEL_ERROR, FLAGS=ROS_TRACING_DEBUG}(ROS_ASSERT_EXP); -// USEPREFIX (ROS_ASSERT, "%!STDPREFIX! [%s @ %u] ASSERTION :%s", __FILE__, __LINE__, #ROS_ASSERT_EXP); -// -// end_wpp - - -// -// ROS_LOG... customization -// - -#define WPP_LEVEL_FLAGS_POST(LEVEL,FLAGS) \ - ,(((WPP_BIT_ ## FLAGS) == WPP_BIT_ROS_TRACING_BUGCHECK) ? \ - _RosLogBugcheck(LEVEL) : \ - (((WPP_BIT_ ## FLAGS) == WPP_BIT_ROS_TRACING_DEBUG) ? \ - _RosLogDebug(LEVEL) : 1)) - -// -// ROS_CRTITICAL_ASSERT customization -// - -#define WPP_RECORDER_LEVEL_FLAGS_ROS_CRIT_ASSERT_EXP_FILTER(LEVEL, FLAGS, ROS_CRIT_ASSERT_EXP) \ - (!(ROS_CRIT_ASSERT_EXP)) - -#define WPP_RECORDER_LEVEL_FLAGS_ROS_CRIT_ASSERT_EXP_ARGS(LEVEL, FLAGS, ROS_CRIT_ASSERT_EXP) \ - WPP_CONTROL(WPP_BIT_ ## FLAGS).AutoLogContext, LEVEL, WPP_BIT_ ## FLAGS - -#define WPP_LEVEL_FLAGS_ROS_CRIT_ASSERT_EXP_POST(LEVEL, FLAGS, ROS_CRIT_ASSERT_EXP) \ - ,((!(ROS_CRIT_ASSERT_EXP)) ? _RosLogBugcheck(LEVEL) : 1) - -// -// ROS_ASSERT customization -// - -#define WPP_RECORDER_LEVEL_FLAGS_ROS_ASSERT_EXP_FILTER(LEVEL, FLAGS, ROS_ASSERT_EXP) \ - (!(ROS_ASSERT_EXP)) - -#define WPP_RECORDER_LEVEL_FLAGS_ROS_ASSERT_EXP_ARGS(LEVEL, FLAGS, ROS_ASSERT_EXP) \ - WPP_CONTROL(WPP_BIT_ ## FLAGS).AutoLogContext, LEVEL, WPP_BIT_ ## FLAGS - -#define WPP_LEVEL_FLAGS_ROS_ASSERT_EXP_POST(LEVEL, FLAGS, ROS_ASSERT_EXP) \ - ,((!(ROS_ASSERT_EXP)) ? _RosLogDebug(LEVEL) : 1) - - -#ifdef __cplusplus -} // extern "C" -#endif // __cplusplus - -#endif // _ROSLOGGING_H_ +#include +#endif // _ROSKMDLOGGING_H_ diff --git a/render-only-sample/roskmd/RosKmdRapAdapter.cpp b/render-only-sample/roskmd/RosKmdRapAdapter.cpp index baf305e..db60a69 100644 --- a/render-only-sample/roskmd/RosKmdRapAdapter.cpp +++ b/render-only-sample/roskmd/RosKmdRapAdapter.cpp @@ -502,6 +502,10 @@ RosKmdRapAdapter::ProcessRenderBuffer( m_renderingControlListPhysicalAddress + m_busAddressOffset, m_renderingControlListPhysicalAddress + m_busAddressOffset + renderingControlListLength); + ROS_LOG_TRACE( + "Completed rendering to 0x%p", + pDmaBufInfo->m_RenderTargetVirtualAddress); + MoveToNextBinnerRenderMemChunk(renderingControlListLength); // diff --git a/render-only-sample/roskmd/Vc4Display.cpp b/render-only-sample/roskmd/Vc4Display.cpp index 8a03651..822c27a 100644 --- a/render-only-sample/roskmd/Vc4Display.cpp +++ b/render-only-sample/roskmd/Vc4Display.cpp @@ -57,10 +57,43 @@ NTSTATUS VC4_DISPLAY::SetVidPnSourceAddress ( { NT_ASSERT(Args->VidPnSourceId == 0); + const auto rosKmdAllocation = + static_cast(Args->hAllocation); + if (Args->Flags.ModeChange) { NT_ASSERT(Args->ContextCount == 0); - ROS_LOG_WARNING("Mode change was requested. Not sure what to do."); + const D3DKMDT_GRAPHICS_RENDERING_FORMAT* currentSourceModePtr = + &this->dxgkCurrentSourceMode.Format.Graphics; + + NT_ASSERT(rosKmdAllocation->m_isPrimary); + const DXGI_DDI_MODE_DESC* desiredModeDescPtr = + &rosKmdAllocation->m_primaryDesc.ModeDesc; + + // Verify that the surface is compatible with the current source mode + if ((desiredModeDescPtr->Width != + currentSourceModePtr->PrimSurfSize.cx) || + (desiredModeDescPtr->Height != + currentSourceModePtr->PrimSurfSize.cy) || + (TranslateDxgiFormat(rosKmdAllocation->m_format) != + currentSourceModePtr->PixelFormat)) + { + ROS_LOG_ASSERTION( + "Incompatible mode change was requested. " + "(desiredModeDescPtr->Width/Height = (%d,%d), " + "TranslateDxgiFormat(rosKmdAllocation->m_primaryDesc.Format) = %d, " + "currentSourceModePtr->PrimSurfSize = (%d,%d), " + "currentSourceModePtr->PixelFormat = %d", + desiredModeDescPtr->Width, + desiredModeDescPtr->Height, + TranslateDxgiFormat(rosKmdAllocation->m_format), + currentSourceModePtr->PrimSurfSize.cx, + currentSourceModePtr->PrimSurfSize.cy, + currentSourceModePtr->PixelFormat); + + return STATUS_NOT_SUPPORTED; + } + return STATUS_SUCCESS; } @@ -88,10 +121,7 @@ NTSTATUS VC4_DISPLAY::SetVidPnSourceAddress ( // Verify memory is in range NT_ASSERT(Args->PrimarySegment == ROSD_SEGMENT_VIDEO_MEMORY); NT_ASSERT(Args->PrimaryAddress.LowPart < RosKmdGlobal::s_videoMemorySize); - if (Args->hAllocation) { - const auto rosKmdAllocation = - static_cast(Args->hAllocation); - UNREFERENCED_PARAMETER(rosKmdAllocation); + if (rosKmdAllocation) { NT_ASSERT( (Args->PrimaryAddress.LowPart + rosKmdAllocation->m_hwSizeBytes) <= RosKmdGlobal::s_videoMemorySize); diff --git a/render-only-sample/roskmd/precomp.h b/render-only-sample/roskmd/precomp.h index 318de05..a7ed576 100644 --- a/render-only-sample/roskmd/precomp.h +++ b/render-only-sample/roskmd/precomp.h @@ -12,4 +12,5 @@ extern "C" { #include #include -}; // extern "C" +#include +} // extern "C" diff --git a/render-only-sample/rostest/RenderingTests.cpp b/render-only-sample/rostest/RenderingTests.cpp new file mode 100644 index 0000000..3314448 --- /dev/null +++ b/render-only-sample/rostest/RenderingTests.cpp @@ -0,0 +1,14 @@ +#include "precomp.h" + +#include "util.h" +#include "RenderingTests.h" + +using namespace Microsoft::WRL; +using namespace Microsoft::WRL::Wrappers; +using namespace WEX::TestExecution; + +bool RenderingTests::ClassSetup () +{ + CreateDevice(&m_device, &m_context); + return true; +} diff --git a/render-only-sample/rostest/RenderingTests.h b/render-only-sample/rostest/RenderingTests.h new file mode 100644 index 0000000..e9cb1ea --- /dev/null +++ b/render-only-sample/rostest/RenderingTests.h @@ -0,0 +1,18 @@ +#ifndef _RENDERING_TESTS_H_ +#define _RENDERING_TESTS_H_ + +// +// Tests related to rendering +// +class RenderingTests { + BEGIN_TEST_CLASS(RenderingTests) + TEST_CLASS_PROPERTY(L"ThreadingModel", L"MTA") + END_TEST_CLASS() + + TEST_CLASS_SETUP(ClassSetup) + + Microsoft::WRL::ComPtr m_device; + Microsoft::WRL::ComPtr m_context; +}; + +#endif // _RENDERING_TESTS_H_ diff --git a/render-only-sample/rostest/ResourceTests.cpp b/render-only-sample/rostest/ResourceTests.cpp new file mode 100644 index 0000000..8b6df02 --- /dev/null +++ b/render-only-sample/rostest/ResourceTests.cpp @@ -0,0 +1,54 @@ +#include "precomp.h" + +#include "util.h" +#include "ResourceTests.h" + +using namespace Microsoft::WRL; +using namespace Microsoft::WRL::Wrappers; +using namespace WEX::TestExecution; + +bool ResourceTests::ClassSetup () +{ + CreateDevice(&m_device, &m_context); + return true; +} + +// TODO: this doesn't seem like a very good test ... +void ResourceTests::TestShaderConstantBuffer () +{ + UINT32 data[1024]; + std::iota(std::begin(data), std::end(data), 0); + + D3D11_BUFFER_DESC desc = {}; + { + desc.BindFlags = D3D11_BIND_CONSTANT_BUFFER; + desc.ByteWidth = sizeof(data); + desc.CPUAccessFlags = 0; // no CPU access + desc.MiscFlags = 0; + desc.StructureByteStride = 0; + desc.Usage = D3D11_USAGE_DEFAULT; // read and write access by GPU + } + + D3D11_SUBRESOURCE_DATA subresourceData = {}; + { + subresourceData.pSysMem = data; + subresourceData.SysMemPitch = 0; + subresourceData.SysMemSlicePitch = 0; + } + + ComPtr bufferA; + VERIFY_SUCCEEDED( + m_device->CreateBuffer(&desc, &subresourceData, &bufferA), + L"Creating constant buffer A"); + + ComPtr bufferB; + VERIFY_SUCCEEDED( + m_device->CreateBuffer(&desc, &subresourceData, &bufferB), + L"Creating constant buffer B"); + + LogComment(L"Copying buffer"); + m_context->CopyResource(bufferB.Get(), bufferA.Get()); + + LogComment(L"Flushing device context"); + m_context->Flush(); +} diff --git a/render-only-sample/rostest/ResourceTests.h b/render-only-sample/rostest/ResourceTests.h new file mode 100644 index 0000000..33cc23e --- /dev/null +++ b/render-only-sample/rostest/ResourceTests.h @@ -0,0 +1,24 @@ +#ifndef _RESOURCE_TESTS_H_ +#define _RESOURCE_TESTS_H_ + +// +// Tests related to resources (creating, copying, updating, mapping, etc..) +// +class ResourceTests { + BEGIN_TEST_CLASS(ResourceTests) + TEST_CLASS_PROPERTY(L"ThreadingModel", L"MTA") + END_TEST_CLASS() + + TEST_CLASS_SETUP(ClassSetup) + + BEGIN_TEST_METHOD(TestShaderConstantBuffer) + TEST_METHOD_PROPERTY( + L"Description", + L"Verifies that a constant buffer can be created and copied.") + END_TEST_METHOD() + + Microsoft::WRL::ComPtr m_device; + Microsoft::WRL::ComPtr m_context; +}; + +#endif // _RESOURCE_TESTS_H_ diff --git a/render-only-sample/rostest/TestData.xml b/render-only-sample/rostest/TestData.xml new file mode 100644 index 0000000..3a30494 --- /dev/null +++ b/render-only-sample/rostest/TestData.xml @@ -0,0 +1,33 @@ + + + + + + + Whatup! + + ]]> + + + + + + + + ]]> + + +
+
diff --git a/render-only-sample/rostest/TestResource.rc b/render-only-sample/rostest/TestResource.rc new file mode 100644 index 0000000..fd5c69d --- /dev/null +++ b/render-only-sample/rostest/TestResource.rc @@ -0,0 +1,2 @@ + +TestData.xml DATASOURCE_XML "TestData.xml" \ No newline at end of file diff --git a/render-only-sample/rostest/XamlTests.cpp b/render-only-sample/rostest/XamlTests.cpp new file mode 100644 index 0000000..daef806 --- /dev/null +++ b/render-only-sample/rostest/XamlTests.cpp @@ -0,0 +1,147 @@ +#include "precomp.h" + +#include "util.h" +#include "XamlTests.h" + +using namespace ABI::Windows::Foundation; +using namespace ABI::Windows::ApplicationModel::Core; +using namespace ABI::Windows::UI::Core; +using namespace ABI::Windows::UI::Xaml; +using namespace ABI::Windows::UI::Xaml::Markup; +using namespace Microsoft::WRL; +using namespace Microsoft::WRL::Wrappers; +using namespace WEX::TestExecution; + +ComPtr GetCurrentWindow () +{ + ComPtr windowStatics; + VERIFY_SUCCEEDED( + Windows::Foundation::GetActivationFactory( + HStringReference(RuntimeClass_Windows_UI_Xaml_Window).Get(), + &windowStatics), + L"Getting IWindowStatics"); + + ComPtr currentWindow; + VERIFY_SUCCEEDED( + windowStatics->get_Current(¤tWindow), + L"Getting current window"); + + return currentWindow; +} + +ComPtr XamlFromString (PCWSTR XamlStr) +{ + ComPtr xamlReaderStatics; + VERIFY_SUCCEEDED( + Windows::Foundation::GetActivationFactory( + HStringReference(RuntimeClass_Windows_UI_Xaml_Markup_XamlReader).Get(), + &xamlReaderStatics), + L"Getting IXamlReaderStatics"); + + ComPtr inspectable; + VERIFY_SUCCEEDED( + xamlReaderStatics->Load(HStringReference(XamlStr).Get(), &inspectable), + L"Loading XAML string"); + + ComPtr uiElement; + VERIFY_SUCCEEDED( + inspectable.As(&uiElement), + L"Doing QueryInterface for IUIElement"); + + return uiElement; +} + +void SetXamlContent (PCWSTR XamlString) +{ + // Load the XAML content + auto uiElement = XamlFromString(XamlString); + + // Set it as the Window's content + VERIFY_SUCCEEDED( + GetCurrentWindow()->put_Content(uiElement.Get()), + L"Setting UI element as root of window"); +} + +bool XamlTests::ClassSetup () +{ + return true; +} + +// +// The purpose of this test is to demonstrate how to use RunOnUIThread +// and how to attach/detach a XAML event handler. This test does no actual +// verification. +// +void XamlTests::TestResizeWindow () +{ + // run on UI thread + AgileRef agileWindow; + EventRegistrationToken token; + HRESULT hr = RunOnUIThread([&] + { + auto currentWindow = GetCurrentWindow(); + + VERIFY_SUCCEEDED( + currentWindow.AsAgile(&agileWindow), + L"Getting agile window reference"); + + boolean visible; + VERIFY_SUCCEEDED( + currentWindow->get_Visible(&visible), + L"Getting visibility of current window"); + + LogComment(L"Current window visibility: %d", visible); + + Rect bounds; + VERIFY_SUCCEEDED( + currentWindow->get_Bounds(&bounds), + L"Getting bounds"); + + LogComment( + L"Current window has bounds [%f %f %f %f]", + bounds.X, + bounds.Y, + bounds.Width, + bounds.Height); + + + HRESULT hr = currentWindow->add_SizeChanged( + Callback([&] ( + IInspectable* /*Sender*/, + IWindowSizeChangedEventArgs* Args + ) + { + Size size; + VERIFY_SUCCEEDED(Args->get_Size(&size)); + + LogComment(L"Size is [%f, %f]", size.Width, size.Height); + + return S_OK; + }).Get(), + &token); + + VERIFY_SUCCEEDED(hr, L"Verifying add_SizeChanged succeeded"); + }); + VERIFY_SUCCEEDED(hr, L"Verifying that UI thread operation succeeded"); + + Sleep(5000); + + RunOnUIThread([&] { GetCurrentWindow()->remove_SizeChanged(token); }); +} + +void XamlTests::TestLoadXaml () +{ + WEX::Common::String xamlString; + VERIFY_SUCCEEDED( + TestData::TryGetValue(L"Xaml", xamlString), + L"Getting XAML fragment from test data"); + + HRESULT hr = RunOnUIThread([&] + { + SetXamlContent(xamlString.operator const wchar_t*()); + }); + + VERIFY_SUCCEEDED(hr, L"Verifying that UI thread operation succeeded"); + + Sleep(1000); +} diff --git a/render-only-sample/rostest/XamlTests.h b/render-only-sample/rostest/XamlTests.h new file mode 100644 index 0000000..0a4764c --- /dev/null +++ b/render-only-sample/rostest/XamlTests.h @@ -0,0 +1,27 @@ +#ifndef _XAMLTESTS_H_ +#define _XAMLTESTS_H_ + +class XamlTests { + BEGIN_TEST_CLASS(XamlTests) + TEST_CLASS_PROPERTY(L"RunAs", L"UAP") + TEST_CLASS_PROPERTY(L"UAP:Host", L"XAML") + END_TEST_CLASS() + + TEST_CLASS_SETUP(ClassSetup) + + BEGIN_TEST_METHOD(TestResizeWindow) + TEST_METHOD_PROPERTY( + L"Description", + L"Shows how to use RunOnUIThread and attach event handlers to " + L"WinRT objects.") + END_TEST_METHOD() + + BEGIN_TEST_METHOD(TestLoadXaml) + TEST_METHOD_PROPERTY(L"DataSource", L"Table:TestData.xml#XamlControls") + TEST_METHOD_PROPERTY( + L"Description", + L"Shows how to load XAML from a string and display in current window") + END_TEST_METHOD() +}; + +#endif // _XAMLTESTS_H_ diff --git a/render-only-sample/rostest/precomp.cpp b/render-only-sample/rostest/precomp.cpp new file mode 100644 index 0000000..ceeb0d6 --- /dev/null +++ b/render-only-sample/rostest/precomp.cpp @@ -0,0 +1 @@ +#include "precomp.h" diff --git a/render-only-sample/rostest/precomp.h b/render-only-sample/rostest/precomp.h new file mode 100644 index 0000000..86700c2 --- /dev/null +++ b/render-only-sample/rostest/precomp.h @@ -0,0 +1,19 @@ +#ifndef _PRECOMP_H_ +#define _PRECOMP_H_ + +#include +#undef GetCurrentTime + +#include + +#include +#include +#include +#include + +#include +#include + +#include // std::iota + +#endif // _PRECOMP_H_ diff --git a/render-only-sample/rostest/rostest.vcxproj b/render-only-sample/rostest/rostest.vcxproj index ed954bc..c2e88b9 100644 --- a/render-only-sample/rostest/rostest.vcxproj +++ b/render-only-sample/rostest/rostest.vcxproj @@ -1,18 +1,18 @@  - + Debug - arm + ARM + + + Release + ARM Debug Win32 - - Release - arm - Release Win32 @@ -27,214 +27,94 @@ - {55C9EAC8-81E0-467D-B0D4-631B201AE621} - Win32Proj - rostest + {5E7D4E14-5AF2-48AB-A551-33C8865A3C47} + RosTest 10.0.10586.0 + true - - Application + true + DynamicLibrary v140 Unicode - false - - Application + true - v140 - Unicode - false - - Application + false - v140 true - Unicode - false - - - Application - false - v140 - true - Unicode - false - - - Application - true - v140 - Unicode - false - - - Application - false - v140 - true - Unicode - false - - - - - - - - - - - - - - - - + - - true - - - true - - - true - - - false - - - false - - - false - - + + - - - Level3 - Disabled - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - MultiThreadedDebug + Use + precomp.h + $(WindowsSdkDir)\Testing\Development\inc;%(AdditionalIncludeDirectories) - Console - true - mincore.lib;d3d11.lib;dxgi.lib; - kernel32.lib;%(IgnoreSpecificDefaultLibraries) + true + Te.Common.lib;Wex.Common.Lib;Wex.Logger.lib;onecoreuap.lib; + $(WindowsSdkDir)\Testing\Development\lib\$(PlatformTarget)\;%(AdditionalLibraryDirectories) - + - - - Level3 + Level4 + true Disabled - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - MultiThreadedDebug + true + true - Console - true - mincore.lib;d3d11.lib;dxgi.lib; - kernel32.lib;%(IgnoreSpecificDefaultLibraries) + msvcrtd.lib;vcruntimed.lib;ucrtd.lib;msvcprtd.lib;%(AdditionalDependencies) - + - - - Level3 - Disabled - _DEBUG;_CONSOLE;%(PreprocessorDefinitions) - MultiThreadedDebug - - - Console - true - mincore.lib;d3d11.lib;dxgi.lib; - kernel32.lib;%(IgnoreSpecificDefaultLibraries) - - - - - Level3 - - + Level4 + true MaxSpeed true true - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - MultiThreaded + true - Console - true + msvcrt.lib;vcruntime.lib;ucrt.lib;msvcprt.lib;%(AdditionalDependencies) true true - mincore.lib;d3d11.lib;dxgi.lib; - kernel32.lib;%(IgnoreSpecificDefaultLibraries) - - - Level3 - - - MaxSpeed - true - true - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - MultiThreaded - - - Console - true - true - true - mincore.lib;d3d11.lib;dxgi.lib; - kernel32.lib;%(IgnoreSpecificDefaultLibraries) - - - - - Level3 - NotUsing - MaxSpeed - true - true - NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - MultiThreaded + + + Create - - Console - true - true - true - mincore.lib;d3d11.lib;dxgi.lib; - kernel32.lib;%(IgnoreSpecificDefaultLibraries) - - + + + + +
- - + + + + + - + - \ No newline at end of file + diff --git a/render-only-sample/rostest/rostest.vcxproj.filters b/render-only-sample/rostest/rostest.vcxproj.filters index 6a5e1e0..432fd8e 100644 --- a/render-only-sample/rostest/rostest.vcxproj.filters +++ b/render-only-sample/rostest/rostest.vcxproj.filters @@ -15,16 +15,37 @@ - + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + Header Files - + + Header Files + + + Header Files + + + Header Files + + Header Files - - - - Source Files - \ No newline at end of file diff --git a/render-only-sample/rostest/stdafx.h b/render-only-sample/rostest/stdafx.h deleted file mode 100644 index b005a83..0000000 --- a/render-only-sample/rostest/stdafx.h +++ /dev/null @@ -1,15 +0,0 @@ -// stdafx.h : include file for standard system include files, -// or project specific include files that are used frequently, but -// are changed infrequently -// - -#pragma once - -#include "targetver.h" - -#include -#include - - - -// TODO: reference additional headers your program requires here diff --git a/render-only-sample/rostest/targetver.h b/render-only-sample/rostest/targetver.h deleted file mode 100644 index 87c0086..0000000 --- a/render-only-sample/rostest/targetver.h +++ /dev/null @@ -1,8 +0,0 @@ -#pragma once - -// Including SDKDDKVer.h defines the highest available Windows platform. - -// If you wish to build your application for a previous Windows platform, include WinSDKVer.h and -// set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h. - -#include diff --git a/render-only-sample/rostest/util.cpp b/render-only-sample/rostest/util.cpp new file mode 100644 index 0000000..b8a27ea --- /dev/null +++ b/render-only-sample/rostest/util.cpp @@ -0,0 +1,231 @@ +#include "precomp.h" +#include "util.h" + +using namespace Microsoft::WRL; +using namespace WEX::TestExecution; + +PCWSTR StringFromFeatureLevel (D3D_FEATURE_LEVEL FeatureLevel) +{ + switch (FeatureLevel) { + case D3D_FEATURE_LEVEL_12_1: return L"12.1"; + case D3D_FEATURE_LEVEL_12_0: return L"12.0"; + case D3D_FEATURE_LEVEL_11_1: return L"11.1"; + case D3D_FEATURE_LEVEL_11_0: return L"11.0"; + case D3D_FEATURE_LEVEL_10_1: return L"10.1"; + case D3D_FEATURE_LEVEL_10_0: return L"10.0"; + case D3D_FEATURE_LEVEL_9_3: return L"9.3"; + case D3D_FEATURE_LEVEL_9_2: return L"9.2"; + case D3D_FEATURE_LEVEL_9_1: return L"9.1"; + default: + throw MyException::Make( + E_INVALIDARG, + L"Invalid feature level: %d", + FeatureLevel); + } +} + +ComPtr FindAdapter (PCWSTR Description) +{ + ComPtr factory; + VERIFY_SUCCEEDED( + CreateDXGIFactory2( + 0, + __uuidof(factory), + reinterpret_cast(factory.GetAddressOf())), + L"Verifying that CreateDXGIFactory2() succeeded"); + + + for (UINT adapterIndex = 0; ; ++adapterIndex) { + ComPtr adapter1; + HRESULT hr = factory->EnumAdapters1(adapterIndex, &adapter1); + if (FAILED(hr)) { + if (hr == DXGI_ERROR_NOT_FOUND) + break; + + VERIFY_SUCCEEDED( + hr, + L"Verifying that factory->EnumAdapters1(...) succeeded"); + } + + ComPtr adapter2; + VERIFY_SUCCEEDED( + adapter1.As(&adapter2), + L"Doing QI for IDXGIAdapter2"); + + DXGI_ADAPTER_DESC2 desc; + VERIFY_SUCCEEDED( + adapter2->GetDesc2(&desc), + L"Getting DXGI_ADAPTER_DESC2 from adapter"); + + if (wcscmp(Description, desc.Description) == 0) { + LogComment(L"Found adapter: %s", Description); + return adapter2; + } + } + + throw MyException::Make( + DXGI_ERROR_NOT_FOUND, + L"The specified adapter could not be found: %s", + Description); +} + +// +// TAEF runtime parameters affecting this method: +// +// Adapter=Ros|Warp|Default +// Specify whether to use the default adapter, ROS, or WARP. +// The default is to use ROS. +// +// NoDebugLayer=true|false +// Specify whether to create the device with the debug layer. +// The default is to create the device with the debug layer. +// +// MaxFeatureLevel=12.1|12.0|11.1|11.0|10.1|10.0|9.3|9.2|9.1 +// Specify the highest feature level to be used. For example, +// if you specify a maximum feature level of 10.1, the device will be +// created with feature level 10.1, 10.0, 9.3, etc. +// The default is 12.1. +// +void CreateDevice ( + _COM_Outptr_ ID3D11Device3** DevicePPtr, + _COM_Outptr_ ID3D11DeviceContext3** ContextPPtr + ) +{ + *DevicePPtr = nullptr; + *ContextPPtr = nullptr; + + HRESULT hr; + + ComPtr adapter; + D3D_DRIVER_TYPE driverType; + { + WEX::Common::String adapterStr; + hr = RuntimeParameters::TryGetValue(L"Adapter", adapterStr); + if (SUCCEEDED(hr)) { + if (_wcsicmp((const wchar_t*)adapterStr, L"Default") == 0) { + driverType = D3D_DRIVER_TYPE_HARDWARE; + adapter = nullptr; + } else if (_wcsicmp((const wchar_t*)adapterStr, L"Ros") == 0) { + driverType = D3D_DRIVER_TYPE_UNKNOWN; + adapter = FindAdapter(ROS_DRIVER_NAME_WSZ); + } else if (_wcsicmp((const wchar_t*)adapterStr, L"Warp") == 0) { + driverType = D3D_DRIVER_TYPE_WARP; + adapter = nullptr; + } else { + throw MyException::Make( + E_INVALIDARG, + L"Invalid Adapter value: %s. " + L"Valid values are: Default, Ros, Warp", + (const wchar_t*)adapterStr); + } + } else { + // default to using ROS + driverType = D3D_DRIVER_TYPE_UNKNOWN; + adapter = FindAdapter(ROS_DRIVER_NAME_WSZ); + } + } + + UINT creationFlags = D3D11_CREATE_DEVICE_BGRA_SUPPORT; + { + bool noDebugLayer; + hr = RuntimeParameters::TryGetValue(L"NoDebugLayer", noDebugLayer); + if (SUCCEEDED(hr) && noDebugLayer) { + LogComment(L"Creating device WITHOUT debug layer."); + } else { + LogComment(L"Creating device with debug layer."); + creationFlags |= D3D11_CREATE_DEVICE_DEBUG; + } + } + + const D3D_FEATURE_LEVEL featureLevels[] = { + D3D_FEATURE_LEVEL_12_1, + D3D_FEATURE_LEVEL_12_0, + D3D_FEATURE_LEVEL_11_1, + D3D_FEATURE_LEVEL_11_0, + D3D_FEATURE_LEVEL_10_1, + D3D_FEATURE_LEVEL_10_0, + D3D_FEATURE_LEVEL_9_3, + D3D_FEATURE_LEVEL_9_2, + D3D_FEATURE_LEVEL_9_1 + }; + + PCWSTR const featureLevelStrings[] = { + L"12.1", + L"12.0", + L"11.1", + L"11.0", + L"10.1", + L"10.0", + L"9.3", + L"9.2", + L"9.1" + }; + + static_assert( + ARRAYSIZE(featureLevels) == ARRAYSIZE(featureLevelStrings), + "featureLevels and featureLevelStrings must have same number of elements"); + + int featureLevelIndex; + { + WEX::Common::String featureLevelStr; + hr = RuntimeParameters::TryGetValue(L"MaxFeatureLevel", featureLevelStr); + if (SUCCEEDED(hr)) { + int i; + for (i = 0; i < ARRAYSIZE(featureLevelStrings); ++i) { + if (featureLevelStr == featureLevelStrings[i]) { + LogComment( + L"Will create device with feature level no higher than %s", + featureLevelStr.operator const wchar_t*()); + break; + } + } + + if (i == ARRAYSIZE(featureLevelStrings)) { + throw MyException::Make( + E_INVALIDARG, + L"Invalid feature level: %s. Valid feature levels are " + L"12.1, 12.0, 11.1, 11.0, 10.1, 10.0, 9.3, 9.2, 9.1", + featureLevelStr.operator const wchar_t*()); + } + + featureLevelIndex = i; + } else { + featureLevelIndex = 0; + } + } + + ComPtr device; + ComPtr context; + D3D_FEATURE_LEVEL selectedFeatureLevel; + hr = D3D11CreateDevice( + adapter.Get(), + driverType, + 0, + creationFlags, + featureLevels + featureLevelIndex, + ARRAYSIZE(featureLevels) - featureLevelIndex, + D3D11_SDK_VERSION, + &device, + &selectedFeatureLevel, + &context); + if (FAILED(hr)) { + throw MyException::Make(hr, L"D3D11CreateDevice(...) failed."); + } + + LogComment( + L"Successfully created device. Selected feature level: %s", + StringFromFeatureLevel(selectedFeatureLevel)); + + ComPtr device3; + VERIFY_SUCCEEDED( + device.As(&device3), + L"Doing QI for ID3DDevice3"); + + ComPtr context3; + VERIFY_SUCCEEDED( + context.As(&context3), + L"Doing QI for ID3D11DeviceContext3"); + + *DevicePPtr = device3.Detach(); + *ContextPPtr = context3.Detach(); +} \ No newline at end of file diff --git a/render-only-sample/rostest/util.h b/render-only-sample/rostest/util.h new file mode 100644 index 0000000..a143d9c --- /dev/null +++ b/render-only-sample/rostest/util.h @@ -0,0 +1,177 @@ +#ifndef _ROSTEST_UTIL_H_ +#define _ROSTEST_UTIL_H_ + +#define ROS_DRIVER_NAME_WSZ L"Render Only Sample Driver" + +#define LogComment(fmt, ...) WEX::Logging::Log::Comment( \ + WEX::Common::NoThrowString().Format((fmt), __VA_ARGS__)) + +#define LogWarning(fmt, ...) WEX::Logging::Log::Warning( \ + WEX::Common::NoThrowString().Format((fmt), __VA_ARGS__)) + +#define LogError(fmt, ...) WEX::Logging::Log::Error( \ + WEX::Common::NoThrowString().Format((fmt), __VA_ARGS__)) + +template +HRESULT RunOnUIThread (const TFunction& Function) +{ + using namespace ABI::Windows::Foundation; + using namespace ABI::Windows::ApplicationModel::Core; + using namespace ABI::Windows::UI::Core; + using namespace Microsoft::WRL; + + // Get the ICoreApplication + ComPtr application; + HRESULT hr = Windows::Foundation::GetActivationFactory( + Wrappers::HStringReference( + RuntimeClass_Windows_ApplicationModel_Core_CoreApplication).Get(), + &application); + if (FAILED(hr)) + { + return hr; + } + + // Get the ICoreApplicationView + ComPtr view; + hr = application->get_MainView(&view); + if (FAILED(hr)) + { + return hr; + } + + // Get the ICoreWindow + ComPtr window; + hr = view->get_CoreWindow(&window); + if (FAILED(hr)) + { + return hr; + } + + // Get the dispatcher + ComPtr dispatcher; + hr = window->get_Dispatcher(&dispatcher); + if (FAILED(hr)) + { + return hr; + } + + // Create an event so we can wait for the callback to complete + Wrappers::Event completedEvent(CreateEvent(nullptr, TRUE, FALSE, nullptr)); + if (!completedEvent.IsValid()) + { + return HRESULT_FROM_WIN32(::GetLastError()); + } + + // Create the dispatch callback + HRESULT invokeResult = E_FAIL; + + typedef Microsoft::WRL::Implements< + Microsoft::WRL::RuntimeClassFlags<::Microsoft::WRL::ClassicCom>, + ABI::Windows::UI::Core::IDispatchedHandler, + Microsoft::WRL::FtmBase> AgileDispatcherCallback; + auto dispatchCallback = Callback([&] () -> HRESULT + { + invokeResult = WEX::SafeInvoke([&] () -> bool + { + Function(); + return true; + }); + return S_OK; + }); + + if (!dispatchCallback) + { + return E_OUTOFMEMORY; + } + + // Create the completion callback + auto completionCallback = Callback( + [&completedEvent] (IAsyncAction*, AsyncStatus) -> HRESULT + { + return SetEvent(completedEvent.Get()) ? S_OK : E_FAIL; + }); + + if (!completionCallback) + { + return E_OUTOFMEMORY; + } + + // Dispatch the callback + ComPtr asyncAction; + hr = dispatcher->RunAsync( + CoreDispatcherPriority_Normal, + dispatchCallback.Get(), + &asyncAction); + if (FAILED(hr)) + { + return hr; + } + + // Subscribe to its completed event + hr = asyncAction->put_Completed(completionCallback.Get()); + if (FAILED(hr)) + { + return hr; + } + + // Wait for the callback to complete + if (WaitForSingleObject(completedEvent.Get(), INFINITE) != WAIT_OBJECT_0) { + return HRESULT_FROM_WIN32(GetLastError()); + } + + return invokeResult; +} + +// +// An exception deriving from WEX::Common::Exception that can be constructed +// with a printf-style message and explicitly thrown via the 'throw' keyword. +// The problem with VERIFY_ and WEX::Common::Throw::* is that they are functions, +// so the compiler and OACR don't know they cause a change in control flow. +// An explicit 'throw' in the source makes it clear to both the reader +// and compiler that the current scope is being exited via an exception. +// +// Usage: +// throw MyException::Make(E_FAIL, L"Something bad happened (%d)", value); +// +class MyException : public WEX::Common::Exception { +public: + explicit MyException (_In_range_(<, 0) HRESULT Hr) /*noexcept*/ : + Exception(Hr) {} + MyException (_In_range_(<, 0) HRESULT Hr, PCWSTR Message) /*noexcept*/ : + Exception(Hr, Message) {} + + static MyException Make ( + HRESULT HResult, + _In_ _Printf_format_string_ PCWSTR Format, + ... + ) /*noexcept*/ + { + WCHAR buf[512]; + + va_list argList; + va_start(argList, Format); + + HRESULT hr = StringCchVPrintfW( + buf, + ARRAYSIZE(buf), + Format, + argList); + + va_end(argList); + + return MyException(HResult, SUCCEEDED(hr) ? buf : Format); + } + + MyException& operator= (const MyException&) = delete; +}; + +PCWSTR StringFromFeatureLevel (D3D_FEATURE_LEVEL FeatureLevel); + +Microsoft::WRL::ComPtr FindAdapter (PCWSTR Description); + +void CreateDevice ( + _COM_Outptr_ ID3D11Device3** DevicePPtr, + _COM_Outptr_ ID3D11DeviceContext3** ContextPPtr + ); + +#endif // _ROSTEST_UTIL_H_ diff --git a/render-only-sample/rosumd/RosUmd.cpp b/render-only-sample/rosumd/RosUmd.cpp index b3b41ab..47f657b 100644 --- a/render-only-sample/rosumd/RosUmd.cpp +++ b/render-only-sample/rosumd/RosUmd.cpp @@ -1,10 +1,13 @@ -#include -#include +#include "precomp.h" -// TODO[bhouse] Turn ApiValidator back on +#undef WPP_MACRO_USE_KM_VERSION_FOR_UM +#include "RosUmdLogging.h" +#include "RosUmd.tmh" + +#include "roscompiler.h" -void __stdcall InitializeShaderCompilerLibrary(); +// TODO[bhouse] Turn ApiValidator back on HINSTANCE g_hDLL; @@ -15,8 +18,6 @@ BOOL WINAPI DllMain( { lpvReserved; // unused - RosUmdLogging::Entry(__FUNCTION__); - // Warning, do not call outside of this module, except for functions located in kernel32.dll. BUT, do not call LoadLibrary nor // FreeLibrary, either. Nor, call malloc nor new; use HeapAlloc directly. @@ -24,6 +25,10 @@ BOOL WINAPI DllMain( { case( DLL_PROCESS_ATTACH ): { + WPP_INIT_TRACING(L"RosUmd"); + + ROS_LOG_TRACE("RosUmd was loaded. (hmod = 0x%p)", hmod); + InitializeShaderCompilerLibrary(); g_hDLL = hmod; } break; @@ -31,12 +36,12 @@ BOOL WINAPI DllMain( case( DLL_PROCESS_DETACH ): { g_hDLL = NULL; - } break; + WPP_CLEANUP(); + return TRUE; + } default: break; } - RosUmdLogging::Exit(__FUNCTION__); - return TRUE; } diff --git a/render-only-sample/rosumd/RosUmdAdapter.cpp b/render-only-sample/rosumd/RosUmdAdapter.cpp index f4807c4..6e67f4a 100644 --- a/render-only-sample/rosumd/RosUmdAdapter.cpp +++ b/render-only-sample/rosumd/RosUmdAdapter.cpp @@ -1,9 +1,12 @@ +#include "precomp.h" + +#include "RosUmdLogging.h" +#include "RosUmdAdapter.tmh" + #include "RosUmdAdapter.h" #include "RosUmdDevice.h" -#include "RosUmdLogging.h" #include "RosAdapter.h" -#include //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // diff --git a/render-only-sample/rosumd/RosUmdAdapter.h b/render-only-sample/rosumd/RosUmdAdapter.h index 3fea487..f4d1a25 100644 --- a/render-only-sample/rosumd/RosUmdAdapter.h +++ b/render-only-sample/rosumd/RosUmdAdapter.h @@ -7,7 +7,6 @@ //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// #pragma once -#include "d3dumddi_.h" #include "RosAdapter.h" //================================================================================================================================== diff --git a/render-only-sample/rosumd/RosUmdBlendState.h b/render-only-sample/rosumd/RosUmdBlendState.h index fbaf86c..39fb51a 100644 --- a/render-only-sample/rosumd/RosUmdBlendState.h +++ b/render-only-sample/rosumd/RosUmdBlendState.h @@ -1,7 +1,5 @@ #pragma once -#include "d3dumddi_.h" - class RosUmdBlendState { public: diff --git a/render-only-sample/rosumd/RosUmdCommandBuffer.cpp b/render-only-sample/rosumd/RosUmdCommandBuffer.cpp index a60c483..30ffc53 100644 --- a/render-only-sample/rosumd/RosUmdCommandBuffer.cpp +++ b/render-only-sample/rosumd/RosUmdCommandBuffer.cpp @@ -1,8 +1,13 @@ +#include "precomp.h" + +#include "RosUmdLogging.h" +#include "RosUmdCommandBuffer.tmh" + #include "RosUmdCommandBuffer.h" #include "RosUmdResource.h" #include "RosUmdDevice.h" #include "RosUmdDebug.h" -#include + RosUmdCommandBuffer::RosUmdCommandBuffer() { diff --git a/render-only-sample/rosumd/RosUmdCommandBuffer.h b/render-only-sample/rosumd/RosUmdCommandBuffer.h index 23e2110..12b91a6 100644 --- a/render-only-sample/rosumd/RosUmdCommandBuffer.h +++ b/render-only-sample/rosumd/RosUmdCommandBuffer.h @@ -1,6 +1,5 @@ #pragma once -#include "d3dumddi_.h" #include "RosGpuCommand.h" class RosUmdDevice; diff --git a/render-only-sample/rosumd/RosUmdDebug.h b/render-only-sample/rosumd/RosUmdDebug.h index 3c98d9c..8168644 100644 --- a/render-only-sample/rosumd/RosUmdDebug.h +++ b/render-only-sample/rosumd/RosUmdDebug.h @@ -1,8 +1,5 @@ #pragma once -#include -#include - #define assert( _exp ) ( ( _exp ) ? true : (\ OutputDebugStringW( L"Assertion Failed\n" ),\ OutputDebugStringW( #_exp L"\n" ),\ diff --git a/render-only-sample/rosumd/RosUmdDepthStencilState.h b/render-only-sample/rosumd/RosUmdDepthStencilState.h index 840db76..23badb8 100644 --- a/render-only-sample/rosumd/RosUmdDepthStencilState.h +++ b/render-only-sample/rosumd/RosUmdDepthStencilState.h @@ -1,7 +1,5 @@ #pragma once -#include "d3dumddi_.h" - class RosUmdDepthStencilState { friend class RosUmdDevice; diff --git a/render-only-sample/rosumd/RosUmdDepthStencilView.h b/render-only-sample/rosumd/RosUmdDepthStencilView.h index 1a4edbb..8de209e 100644 --- a/render-only-sample/rosumd/RosUmdDepthStencilView.h +++ b/render-only-sample/rosumd/RosUmdDepthStencilView.h @@ -1,7 +1,5 @@ #pragma once -#include "d3dumddi_.h" - class RosUmdDepthStencilView { friend class RosUmdDevice; diff --git a/render-only-sample/rosumd/RosUmdDevice.cpp b/render-only-sample/rosumd/RosUmdDevice.cpp index bb96a2b..e432ed9 100644 --- a/render-only-sample/rosumd/RosUmdDevice.cpp +++ b/render-only-sample/rosumd/RosUmdDevice.cpp @@ -5,6 +5,11 @@ // Copyright (C) Microsoft Corporation // //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#include "precomp.h" + +#include "RosUmdLogging.h" +#include "RosUmdDevice.tmh" + #include "RosUmdDevice.h" #include "RosUmdResource.h" #include "RosUmdDebug.h" @@ -22,10 +27,6 @@ #include "RosContext.h" #include "RosUmdUtil.h" -#include -#include -#include - #if VC4 #include "Vc4Hw.h" @@ -35,8 +36,6 @@ #endif -#include "math.h" - static BOOLEAN _IntersectRect(RECT* CONST pDst, RECT CONST* CONST pSrc1, RECT CONST* CONST pSrc2) { @@ -78,7 +77,8 @@ RosUmdDevice::RosUmdDevice( m_pAdapter(pAdapter), m_Interface(pArgs->Interface), m_hRTDevice(pArgs->hRTDevice), - m_hRTCoreLayer(pArgs->hRTCoreLayer) + m_hRTCoreLayer(pArgs->hRTCoreLayer), + m_bPredicateValue(FALSE) { // Location of function table for runtime callbacks. Can not change these function pointers, as they are runtime-owned; // but the pointer should be saved. Do not cache function pointers, as the runtime may change the table entries at will. @@ -220,7 +220,7 @@ void RosUmdDevice::CreateResource(const D3D11DDIARG_CREATERESOURCE* pCreateResou RosUmdResource* pResource = new (hResource.pDrvPrivate) RosUmdResource(); pResource->Standup(this, pCreateResource, hRTResource); - + // // Constant buffer is created in system memory // @@ -273,6 +273,24 @@ void RosUmdDevice::CreateResource(const D3D11DDIARG_CREATERESOURCE* pCreateResou pResource->m_hKMResource = allocate.hKMResource; pResource->m_hKMAllocation = allocationInfo.hAllocation; } + + ROS_LOG_TRACE( + "Creating resource. " + "(m_hwWidth/HeightPixels = %u,%u " + "m_hwPitchBytes = %u, " + "m_hwSizeBytes = %u, " + "m_isPrimary = %d, " + "m_hRTResource = 0x%p, " + "m_hKMResource = 0x%x, " + "m_hKMAllocation = 0x%x)", + pResource->m_hwWidthPixels, + pResource->m_hwHeightPixels, + pResource->m_hwPitchBytes, + pResource->m_hwSizeBytes, + pResource->m_isPrimary, + pResource->m_hRTResource.handle, + pResource->m_hKMResource, + pResource->m_hKMAllocation); if (pCreateResource->pInitialDataUP != NULL && pCreateResource->pInitialDataUP[0].pSysMem != NULL) { @@ -291,29 +309,11 @@ void RosUmdDevice::CreateResource(const D3D11DDIARG_CREATERESOURCE* pCreateResou } else if (pResource->m_resourceDimension == D3D10DDIRESOURCE_TEXTURE2D) { - if (pResource->m_hwLayout == RosHwLayout::Linear) - { - BYTE * pSrc = (BYTE *)pCreateResource->pInitialDataUP[0].pSysMem; - BYTE * pDst = (BYTE *)lock.pData; - - for (UINT i = 0; i < pResource->m_mip0Info.TexelHeight; i++) - { - memcpy(pDst, pSrc, pCreateResource->pInitialDataUP[0].SysMemPitch); - pSrc += pCreateResource->pInitialDataUP[0].SysMemPitch; - pDst += pResource->m_hwPitchBytes; - } - } - else - { - // Texture tiled mode support - BYTE * pSrc = (BYTE *)pCreateResource->pInitialDataUP[0].pSysMem; - BYTE * pDst = (BYTE *)lock.pData; - UINT rowStride = pCreateResource->pInitialDataUP[0].SysMemPitch; - - // Swizzle texture to HW format - pResource->ConvertBitmapTo4kTileBlocks(pSrc, pDst, rowStride); - } + const BYTE * pSrc = (BYTE *)pCreateResource->pInitialDataUP[0].pSysMem; + BYTE * pDst = (BYTE *)lock.pData; + UINT rowStride = pCreateResource->pInitialDataUP[0].SysMemPitch; + pResource->ConvertInitialTextureFormatToInternal(pSrc, pDst, rowStride); } else { @@ -627,7 +627,7 @@ HRESULT RosUmdDevice::Present(DXGI_DDI_ARG_PRESENT* Args) return E_INVALIDARG; } } - + // Get the allocation for the source resource auto pSrcResource = RosUmdResource::CastFrom(Args->hSurfaceToPresent); @@ -677,17 +677,17 @@ HRESULT RosUmdDevice::RotateResourceIdentities( assert(RosUmdDevice::CastFrom(Args->hDevice) == this); assert(Args->Resources != 0); - + // Save the handles from the first resource const RosUmdResource* const firstResource = RosUmdResource::CastFrom( Args->pResources[0]); RosUmdResource* const lastResource = RosUmdResource::CastFrom( Args->pResources[Args->Resources - 1]); assert(lastResource->CanRotateFrom(firstResource)); - + D3DKMT_HANDLE firstResourceKMResource = firstResource->m_hKMResource; D3DKMT_HANDLE firstResourceKMAllocation = firstResource->m_hKMAllocation; - + for (UINT i = 0; i < (Args->Resources - 1); ++i) { RosUmdResource* rotateTo = RosUmdResource::CastFrom(Args->pResources[i]); @@ -695,7 +695,7 @@ HRESULT RosUmdDevice::RotateResourceIdentities( Args->pResources[i + 1]); assert(rotateTo->CanRotateFrom(rotateFrom)); - + rotateTo->m_hKMResource = rotateFrom->m_hKMResource; rotateTo->m_hKMAllocation = rotateFrom->m_hKMAllocation; } @@ -815,18 +815,29 @@ HRESULT RosUmdDevice::Present1(DXGI_DDI_ARG_PRESENT1* Args) _Use_decl_annotations_ void RosUmdDevice::CheckDirectFlipSupport( D3D10DDI_HDEVICE hDevice, - D3D10DDI_HRESOURCE /*hResource1*/, - D3D10DDI_HRESOURCE /*hResource2*/, + D3D10DDI_HRESOURCE hResource1, + D3D10DDI_HRESOURCE hResource2, UINT CheckDirectFlipFlags, BOOL *pSupported ) { assert(CastFrom(hDevice) == this); assert((CheckDirectFlipFlags & ~D3D11_1DDI_CHECK_DIRECT_FLIP_IMMEDIATE) == 0); - - // We can seamlessly flip video memory between an application's managed - // primary allocations and the DWM's managed primary allocations - *pSupported = TRUE; + + // + // We can only flip to the resource if it has the same format as the + // current primary since we do not support mode change in + // SetVidPnSourceAddress() at this point. + // + const RosUmdResource* currentResourcePtr = RosUmdResource::CastFrom(hResource1); + const RosUmdResource* directFlipResourcePtr = RosUmdResource::CastFrom(hResource2); + + // Resources must have same dimensions and format + *pSupported = + (directFlipResourcePtr->m_mip0Info == currentResourcePtr->m_mip0Info) && + (directFlipResourcePtr->m_format == currentResourcePtr->m_format) && + (directFlipResourcePtr->m_hwPitchBytes == currentResourcePtr->m_hwPitchBytes) && + (directFlipResourcePtr->m_hwSizeBytes == currentResourcePtr->m_hwSizeBytes); } // @@ -1248,18 +1259,22 @@ void RosUmdDevice::SetRasterizerState(RosUmdRasterizerState * pRasterizerState) void RosUmdDevice::SetScissorRects(UINT NumScissorRects, UINT ClearScissorRects, const D3D10_DDI_RECT *pRects) { - // Issue #36 - assert((NumScissorRects + ClearScissorRects) <= 1); +#if VC4 + // VC4 can handle only 1 scissor rect, so take 1st one only. + assert(NumScissorRects <= 1); if (NumScissorRects) { + assert(pRects); m_scissorRectSet = true; m_scissorRect = *pRects; } - if (ClearScissorRects) + else if (ClearScissorRects) { + // When NumScissorRects is zero and ClearScissorRects is not zero, then clear current scissor. m_scissorRectSet = false; ZeroMemory(&m_scissorRect, sizeof(m_scissorRect)); } +#endif // VC4 } void RosUmdDevice::RefreshPipelineState(UINT vertexOffset) @@ -2071,6 +2086,56 @@ void RosUmdDevice::RefreshPipelineState(UINT vertexOffset) #if VC4 +VC4TextureType RosUmdDevice::MapDXGITextureFormatToVC4Type(RosHwLayout layout, DXGI_FORMAT format) +{ + VC4TextureType textureType; + textureType.TextureType = VC4_TEX_RGBA32R; + + // Map texture layout and DXGI format to HW format + // Note: Some of the DXGI formats are emulated (for example, during + // initialization, texture is converted to HW-compatible format) + if (layout == RosHwLayout::Tiled) + { + switch (format) + { + case DXGI_FORMAT_R8G8B8A8_UNORM: + { + textureType.TextureType = VC4_TEX_RGBX8888; + } + break; + case DXGI_FORMAT_R8_UNORM: + { + textureType.TextureType = VC4_TEX_RGBX8888; + } + break; + case DXGI_FORMAT_R8G8_UNORM: + { + textureType.TextureType = VC4_TEX_RGBX8888; + } + break; + case DXGI_FORMAT_A8_UNORM: + { + textureType.TextureType = VC4_TEX_ALPHA; + } + break; + + default: + { + assert(false); + } + break; + } + } + else + { + // todo: create table with modes + // Linear (raster) format + textureType.TextureType = VC4_TEX_RGBA32R; + } + + return textureType; +} + void RosUmdDevice::WriteUniforms( BOOLEAN bPSUniform, VC4_UNIFORM_FORMAT * pUniformEntries, @@ -2119,18 +2184,7 @@ void RosUmdDevice::WriteUniforms( // TODO[indyz]: Support all VC4 texture formats and tiling // - assert(pTexture->m_hwFormat == RosHwFormat::X8888); - - VC4TextureType vc4TextureType; - - if (pTexture->m_hwLayout == RosHwLayout::Tiled) - { - vc4TextureType.TextureType = VC4_TEX_RGBX8888; - } - else - { - vc4TextureType.TextureType = VC4_TEX_RGBA32R; - } + VC4TextureType vc4TextureType = MapDXGITextureFormatToVC4Type(pTexture->m_hwLayout, pTexture->m_format); pVC4TexConfigParam0->TYPE = vc4TextureType.TYPE; @@ -2160,17 +2214,8 @@ void RosUmdDevice::WriteUniforms( pVC4TexConfigParam1->UInt0 = 0; - VC4TextureType vc4TextureType; - - if (pTexture->m_hwLayout == RosHwLayout::Tiled) - { - vc4TextureType.TextureType = VC4_TEX_RGBX8888; - } - else - { - vc4TextureType.TextureType = VC4_TEX_RGBA32R; - } - + VC4TextureType vc4TextureType = MapDXGITextureFormatToVC4Type(pTexture->m_hwLayout, pTexture->m_format); + RosUmdSampler * pSampler = m_pixelSamplers[pCurUniformEntry->samplerConfiguration.samplerIndex]; D3D10_DDI_SAMPLER_DESC * pSamplerDesc = &pSampler->m_desc; @@ -2306,3 +2351,223 @@ void RosUmdDevice::CreateInternalBuffer(RosUmdResource * pRes, UINT size) MAKE_D3D10DDI_HRTRESOURCE(NULL)); } +void RosUmdDevice::SetPredication(D3D10DDI_HQUERY hQuery, BOOL bPredicateValue) +{ + // + // https://msdn.microsoft.com/en-us/library/windows/hardware/ff569547(v=vs.85).aspx + // per doc, hQuery can contain nullptr - supposed to save the predicate value for future use + // + + if (nullptr == hQuery.pDrvPrivate) + { + m_bPredicateValue = bPredicateValue; + } + else + { + // + // TODO: Implement remaining query values other than null + // + + assert(false); + } + + // + // per MDSN Predication should set an error in the case one was seen + // D3D will interpret an error as critical + // + /* + HRESULT hr = S_OK; + + if (FAILED(hr)) + { + SetError(hr); + } + */ +} + +void RosUmdDevice::ResourceCopyRegion11_1( + RosUmdResource *pDestinationResource, + UINT DstSubresource, + UINT DstX, + UINT DstY, + UINT DstZ, + RosUmdResource * pSourceResource, + UINT SrcSubresource, + const D3D10_DDI_BOX* pSrcBox, + UINT copyFlags + ) +{ + bool bCopy = true; + bool bCopyEntireSubresource = false; + + // + // TODO: come back to philosophy if these need to be checked in FREE builds + // + + assert(nullptr != pDestinationResource); + assert(nullptr != pSourceResource); + + // + // https://msdn.microsoft.com/en-us/library/windows/hardware/hh439845(v=vs.85).aspx + // + + if (nullptr == pSrcBox) + { + // + // when pSrcBox is null, copy the entire subresource + // + + bCopyEntireSubresource = true; + } + else if (pSrcBox->left >= pSrcBox->right || + pSrcBox->top >= pSrcBox->bottom || + pSrcBox->front >= pSrcBox->back) + { + // + // pSrcBox is considered empty, don't do anything, and exit + // + + return; + } + else + { + // + // TODO: the pSrcBox must not extend over the edges of the source subregion or the destination subregion + // + } + + // + // both source and destination resources must be the same type of resource + // + + if (pDestinationResource->m_primaryDesc.ModeDesc.Format != pSourceResource->m_primaryDesc.ModeDesc.Format) + { + return; + } + + // + // both source and destination must have format types that are convertible to each other + // + + if (pDestinationResource->m_format == pSourceResource->m_format) + { + bCopy = true; + } + else + { + bCopy = false; + + // + // TOOD: Implement conversion check logic, or DDI for ResourceConvertRegion + // ensure each source and destionation resource format in D3D11DDIARG_CREATERESOURCE.Format supports appropriate conversion + // + + assert(false); + } + + // + // the source and destination resource must not be currently mapped + // + + if (pDestinationResource->IsMapped() || pSourceResource->IsMapped()) + { + return; + } + + // + // TODO: - Honor the copy flags + // + + (copyFlags); //not used yet + + // + // NOTE: for buffers, all coordinates are in bytes. for textures, all coordinates are in pixels + // + + // + // ensure the destination resource not created with D3D10_DDI_USAGE_IMMUTABLE + // + + if (pDestinationResource->m_usage & D3D10_DDI_USAGE_IMMUTABLE) + { + return; + } + + // + // ensure either source or destination has D3D10_DDI_BIND_DEPTH_STENCIL in D3D11DDIARG_CREATERESOURCE.BindFlags OR is a multi - sampled resource : + // then verify pSrcBox is NULL and DstX, DstY and DstZ are 0 + + if ((((pDestinationResource->m_bindFlags & D3D10_DDI_BIND_DEPTH_STENCIL) || pDestinationResource->IsMultisampled()) || + ((pSourceResource->m_bindFlags & D3D10_DDI_BIND_DEPTH_STENCIL) || pSourceResource->IsMultisampled())) && + (nullptr != pSrcBox || 0 != DstX || 0 != DstY || 0 != DstZ)) + { + return; + } + + // + // ensure sub resource indicies are in range + // + + if (DstSubresource >= pDestinationResource->m_arraySize || + SrcSubresource >= pSourceResource->m_arraySize) + { + return; + } + + // + // TODO: ensure the source and destination resources are NOT part of the exact same subresource + // + + // + // TODO: ensure alignment restrictions apply to coordinates + // + + // + // TODO: ensure each source and desitnation resource format in D3D11DDIARG_CREATERESOURCE.Format is in the same typeless group + // + + // + // ensure the source and destination resources have the same number of samples and quality level (except for single sampled resources, which only number of samples are the same) + // + + if (pDestinationResource->m_sampleDesc.Count != pSourceResource->m_sampleDesc.Count || + pDestinationResource->m_sampleDesc.Quality != pSourceResource->m_sampleDesc.Quality) + { + return; + } + + // + // finally perform the copy or convert + // + + if (bCopy) + { + // + // TODO: implement the copy + // + + assert(false); + } + else + { + // + // TODO: convert path + // + + assert(false); + } + + // + // per MDSN ResourceCopyRegion should set an error in the case one was seen + // D3D will interpret an error as critical + // + +/* + HRESULT hr = S_OK; + + if (FAILED(hr)) + { + SetError(hr); + } +*/ +} diff --git a/render-only-sample/rosumd/RosUmdDevice.h b/render-only-sample/rosumd/RosUmdDevice.h index cb9b9ed..edf91b8 100644 --- a/render-only-sample/rosumd/RosUmdDevice.h +++ b/render-only-sample/rosumd/RosUmdDevice.h @@ -7,9 +7,6 @@ //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// #pragma once -#include "d3dumddi_.h" -#include - #include "RosUmdCommandBuffer.h" #include "RosAllocation.h" #include "RosUmdUtil.h" @@ -76,6 +73,7 @@ class RosUmdDevice void OpenResource(const D3D10DDIARG_OPENRESOURCE*, D3D10DDI_HRESOURCE, D3D10DDI_HRTRESOURCE); void DestroyResource(RosUmdResource * pResource); void ResourceCopy(RosUmdResource *pDestinationResource, RosUmdResource * pSourceResource); + void ResourceCopyRegion11_1(RosUmdResource *pDestinationResource, UINT DstSubresource, UINT DstX, UINT DstY, UINT DstZ, RosUmdResource * pSourceResource, UINT SrcSubresource, const D3D10_DDI_BOX* pSrcBox, UINT copyFlags); void ConstantBufferUpdateSubresourceUP(RosUmdResource *pDestinationResource, UINT DstSubresource, _In_opt_ const D3D10_DDI_BOX *pDstBox, _In_ const VOID *pSysMemUP, UINT RowPitch, UINT DepthPitch, UINT CopyFlags); void CreatePixelShader(const UINT* pCode, D3D10DDI_HSHADER hShader, D3D10DDI_HRTSHADER hRTShader, const D3D11_1DDIARG_STAGE_IO_SIGNATURES* pSignatures); @@ -89,6 +87,8 @@ class RosUmdDevice void ResourceMap(RosUmdResource * pResource, UINT subResource, D3D10_DDI_MAP mapType, UINT mapFlags, D3D10DDI_MAPPED_SUBRESOURCE* pMappedSubRes); void ResourceUnmap(RosUmdResource * pResource, UINT subResource); + void SetPredication(D3D10DDI_HQUERY hQuery, BOOL bPredicateValue); + public: void CheckFormatSupport(DXGI_FORMAT inFormat, UINT* pOutFormatSupport); @@ -217,7 +217,6 @@ class RosUmdDevice void SetRasterizerState(RosUmdRasterizerState * pRasterizerState); void SetScissorRects(UINT NumScissorRects, UINT ClearScissorRects, const D3D10_DDI_RECT *pRects); - RosUmdResource * m_vertexBuffers[kMaxVertexBuffers]; UINT m_vertexStrides[kMaxVertexBuffers]; UINT m_vertexOffsets[kMaxVertexBuffers]; @@ -278,6 +277,8 @@ class RosUmdDevice BOOL m_scissorRectSet; D3D10_DDI_RECT m_scissorRect; + BOOL m_bPredicateValue; + public: void CreateInternalBuffer(RosUmdResource * pRes, UINT size); @@ -300,6 +301,10 @@ class RosUmdDevice UINT &curCommandOffset, D3DDDI_PATCHLOCATIONLIST * &pCurPatchLocation); + VC4TextureType MapDXGITextureFormatToVC4Type( + RosHwLayout layout, + DXGI_FORMAT format); + #endif public: diff --git a/render-only-sample/rosumd/RosUmdDeviceDdi.cpp b/render-only-sample/rosumd/RosUmdDeviceDdi.cpp index 9b1934c..5b2fd0e 100644 --- a/render-only-sample/rosumd/RosUmdDeviceDdi.cpp +++ b/render-only-sample/rosumd/RosUmdDeviceDdi.cpp @@ -1,8 +1,12 @@ +#include "precomp.h" + +#include "RosUmdLogging.h" +#include "RosUmdDeviceDdi.tmh" + #include "RosUmdDeviceDdi.h" #include "RosUmdDevice.h" #include "RosUmdResource.h" #include "RosUmdDebug.h" -#include "RosUmdLogging.h" #include "RosUmdRasterizerState.h" #include "RosUmdDepthStencilState.h" #include "RosUmdSampler.h" @@ -15,10 +19,6 @@ #include "RosContext.h" -#include -#include -#include - // // Ddi Tables // @@ -64,7 +64,7 @@ const D3DWDDM1_3DDI_DEVICEFUNCS RosUmdDeviceDdi::s_deviceFuncsWDDM1_3 = RosUmdDeviceDdi::DdiSetRasterizerState, RosUmdDeviceDdi::QueryEnd_Default, RosUmdDeviceDdi::QueryBegin_Default, - RosUmdDeviceDdi::ResourceCopyRegion11_1_Default, + RosUmdDeviceDdi::DdiResourceCopyRegion11_1, RosUmdDeviceDdi::ResourceUpdateSubresourceUP11_1_Default, RosUmdDeviceDdi::SOSetTargets_Default, RosUmdDeviceDdi::DrawAuto_Dirty, @@ -72,7 +72,7 @@ const D3DWDDM1_3DDI_DEVICEFUNCS RosUmdDeviceDdi::s_deviceFuncsWDDM1_3 = RosUmdDeviceDdi::DdiSetScissorRects, RosUmdDeviceDdi::DdiClearRenderTargetView, RosUmdDeviceDdi::DdiClearDepthStencilView, - RosUmdDeviceDdi::SetPredication_Default, + RosUmdDeviceDdi::DdiSetPredication, RosUmdDeviceDdi::QueryGetData_Default, RosUmdDeviceDdi::DdiFlush, RosUmdDeviceDdi::GenerateMips_Default, @@ -130,7 +130,7 @@ const D3DWDDM1_3DDI_DEVICEFUNCS RosUmdDeviceDdi::s_deviceFuncsWDDM1_3 = RosUmdDeviceDdi::DdiDestroyDevice, RosUmdDeviceDdi::SetTextFilter_Default, RosUmdDeviceDdi::DdiResourceCopy, - RosUmdDeviceDdi::ResourceCopyRegion11_1_Default, + RosUmdDeviceDdi::DdiResourceCopyRegion11_1, RosUmdDeviceDdi::DrawIndexedInstancedIndirect_Dirty, RosUmdDeviceDdi::DrawInstancedIndirect_Dirty, @@ -224,8 +224,6 @@ const DXGI1_3_DDI_BASE_FUNCTIONS RosUmdDeviceDdi::s_dxgiDeviceFuncs4 = void APIENTRY RosUmdDeviceDdi::DdiDestroyDevice( D3D10DDI_HDEVICE hDevice) { - RosUmdLogging::Entry(__FUNCTION__); - RosUmdDevice* pRosUmdDevice = RosUmdDevice::CastFrom(hDevice); try { @@ -237,8 +235,6 @@ void APIENTRY RosUmdDeviceDdi::DdiDestroyDevice( { // do nothing } - - RosUmdLogging::Exit(__FUNCTION__); } void APIENTRY RosUmdDeviceDdi::DdiCreateResource( @@ -247,8 +243,6 @@ void APIENTRY RosUmdDeviceDdi::DdiCreateResource( D3D10DDI_HRESOURCE hResource, D3D10DDI_HRTRESOURCE hRTResource) { - RosUmdLogging::Entry(__FUNCTION__); - RosUmdDevice* pRosUmdDevice = RosUmdDevice::CastFrom(hDevice); try { @@ -259,8 +253,6 @@ void APIENTRY RosUmdDeviceDdi::DdiCreateResource( { pRosUmdDevice->SetException(e); } - - RosUmdLogging::Exit(__FUNCTION__); } void APIENTRY RosUmdDeviceDdi::DdiOpenResource( @@ -269,8 +261,6 @@ void APIENTRY RosUmdDeviceDdi::DdiOpenResource( D3D10DDI_HRESOURCE hResource, D3D10DDI_HRTRESOURCE hRTResource) { - RosUmdLogging::Entry(__FUNCTION__); - RosUmdDevice* pRosUmdDevice = RosUmdDevice::CastFrom(hDevice); try { @@ -281,31 +271,23 @@ void APIENTRY RosUmdDeviceDdi::DdiOpenResource( { pRosUmdDevice->SetException(e); } - - RosUmdLogging::Exit(__FUNCTION__); } void APIENTRY RosUmdDeviceDdi::DdiDestroyResource( D3D10DDI_HDEVICE hDevice, D3D10DDI_HRESOURCE hResource) -{ - RosUmdLogging::Entry(__FUNCTION__); - +{ RosUmdDevice* pRosUmdDevice = RosUmdDevice::CastFrom(hDevice); RosUmdResource * pResource = (RosUmdResource *)hResource.pDrvPrivate; pRosUmdDevice->DestroyResource(pResource); - - RosUmdLogging::Exit(__FUNCTION__); } SIZE_T APIENTRY RosUmdDeviceDdi::DdiCalcPrivateShaderResourceViewSize11( D3D10DDI_HDEVICE, const D3D11DDIARG_CREATESHADERRESOURCEVIEW*) { - RosUmdLogging::Call(__FUNCTION__); - return sizeof(RosUmdShaderResourceView); } @@ -315,23 +297,15 @@ void APIENTRY RosUmdDeviceDdi::DdiCreateShaderResourceView11( D3D10DDI_HSHADERRESOURCEVIEW hShaderResourceView, D3D10DDI_HRTSHADERRESOURCEVIEW hRTShaderResourceView) { - RosUmdLogging::Entry(__FUNCTION__); - new(hShaderResourceView.pDrvPrivate) RosUmdShaderResourceView(pCreate, hRTShaderResourceView); - - RosUmdLogging::Exit(__FUNCTION__); } void APIENTRY RosUmdDeviceDdi::DdiDestroyShaderResourceView( D3D10DDI_HDEVICE, D3D10DDI_HSHADERRESOURCEVIEW hShaderResourceView) { - RosUmdLogging::Entry(__FUNCTION__); - RosUmdShaderResourceView * pShaderResourceView = RosUmdShaderResourceView::CastFrom(hShaderResourceView); pShaderResourceView->~RosUmdShaderResourceView(); - - RosUmdLogging::Exit(__FUNCTION__); } void APIENTRY RosUmdDeviceDdi::DdiResourceCopy( @@ -339,8 +313,6 @@ void APIENTRY RosUmdDeviceDdi::DdiResourceCopy( D3D10DDI_HRESOURCE hDestinationResource, D3D10DDI_HRESOURCE hSourceResource) { - RosUmdLogging::Entry(__FUNCTION__); - RosUmdDevice* pRosUmdDevice = RosUmdDevice::CastFrom(hDevice); RosUmdResource * pDestinationResource = (RosUmdResource *)hDestinationResource.pDrvPrivate; RosUmdResource * pSourceResource = (RosUmdResource *)hSourceResource.pDrvPrivate; @@ -354,8 +326,6 @@ void APIENTRY RosUmdDeviceDdi::DdiResourceCopy( { pRosUmdDevice->SetException(e); } - - RosUmdLogging::Exit(__FUNCTION__); } void APIENTRY RosUmdDeviceDdi::DdiConstantBufferUpdateSubresourceUP11_1( @@ -368,8 +338,6 @@ void APIENTRY RosUmdDeviceDdi::DdiConstantBufferUpdateSubresourceUP11_1( UINT DepthPitch, UINT CopyFlags) { - RosUmdLogging::Entry(__FUNCTION__); - RosUmdDevice* pRosUmdDevice = RosUmdDevice::CastFrom(hDevice); RosUmdResource * pResource = (RosUmdResource *)hDstResource.pDrvPrivate; @@ -382,8 +350,6 @@ void APIENTRY RosUmdDeviceDdi::DdiConstantBufferUpdateSubresourceUP11_1( { pRosUmdDevice->SetException(e); } - - RosUmdLogging::Exit(__FUNCTION__); } void APIENTRY RosUmdDeviceDdi::DdiStagingResourceMap( @@ -394,8 +360,6 @@ void APIENTRY RosUmdDeviceDdi::DdiStagingResourceMap( UINT mapFlags, D3D10DDI_MAPPED_SUBRESOURCE* pMappedSubRes) { - RosUmdLogging::Entry(__FUNCTION__); - RosUmdDevice* pRosUmdDevice = RosUmdDevice::CastFrom(hDevice); RosUmdResource * pResource = (RosUmdResource *)hResource.pDrvPrivate; @@ -408,8 +372,6 @@ void APIENTRY RosUmdDeviceDdi::DdiStagingResourceMap( { pRosUmdDevice->SetException(e); } - - RosUmdLogging::Exit(__FUNCTION__); } void APIENTRY RosUmdDeviceDdi::DdiStagingResourceUnmap( @@ -417,8 +379,6 @@ void APIENTRY RosUmdDeviceDdi::DdiStagingResourceUnmap( D3D10DDI_HRESOURCE hResource, UINT subResource) { - RosUmdLogging::Entry(__FUNCTION__); - RosUmdDevice* pRosUmdDevice = RosUmdDevice::CastFrom(hDevice); RosUmdResource * pResource = (RosUmdResource *)hResource.pDrvPrivate; @@ -431,14 +391,10 @@ void APIENTRY RosUmdDeviceDdi::DdiStagingResourceUnmap( { pRosUmdDevice->SetException(e); } - - RosUmdLogging::Exit(__FUNCTION__); } BOOL APIENTRY RosUmdDeviceDdi::DdiFlush(D3D10DDI_HDEVICE hDevice, UINT flushFlags) { - RosUmdLogging::Entry(__FUNCTION__); - RosUmdDevice* pRosUmdDevice = RosUmdDevice::CastFrom(hDevice); BOOL bSuccess = TRUE; @@ -454,8 +410,6 @@ BOOL APIENTRY RosUmdDeviceDdi::DdiFlush(D3D10DDI_HDEVICE hDevice, UINT flushFlag bSuccess = FALSE; } - RosUmdLogging::Exit(__FUNCTION__); - return bSuccess; } @@ -464,8 +418,6 @@ void APIENTRY RosUmdDeviceDdi::DdiCheckFormatSupport( DXGI_FORMAT Format, UINT* pFormatSupport) { - // RosUmdLogging::Call(__FUNCTION__); - RosUmdDevice* pRosUmdDevice = RosUmdDevice::CastFrom(hDevice); pRosUmdDevice->CheckFormatSupport(Format, pFormatSupport); @@ -475,8 +427,6 @@ void APIENTRY RosUmdDeviceDdi::DdiCheckCounterInfo( D3D10DDI_HDEVICE hDevice, D3D10DDI_COUNTER_INFO* pCounterInfo) { - RosUmdLogging::Call(__FUNCTION__); - RosUmdDevice* pRosUmdDevice = RosUmdDevice::CastFrom(hDevice); pRosUmdDevice->CheckCounterInfo(pCounterInfo); } @@ -488,8 +438,6 @@ void APIENTRY RosUmdDeviceDdi::DdiCheckMultisampleQualityLevels( UINT Flags, UINT* pNumQualityLevels) { - // RosUmdLogging::Call(__FUNCTION__); - RosUmdDevice* pRosUmdDevice = RosUmdDevice::CastFrom(hDevice); pRosUmdDevice->CheckMultisampleQualityLevels(Format, SampleCount, Flags, pNumQualityLevels); } @@ -498,8 +446,6 @@ SIZE_T APIENTRY RosUmdDeviceDdi::DdiCalcPrivateResourceSize( D3D10DDI_HDEVICE, const D3D11DDIARG_CREATERESOURCE*) { - RosUmdLogging::Call(__FUNCTION__); - return sizeof(RosUmdResource); } @@ -518,8 +464,6 @@ SIZE_T APIENTRY RosUmdDeviceDdi::DdiCalcRasterizerStateSize( D3D10DDI_HDEVICE, const D3D11_1_DDI_RASTERIZER_DESC*) { - RosUmdLogging::Call(__FUNCTION__); - return sizeof(RosUmdRasterizerState); } @@ -529,8 +473,6 @@ void APIENTRY RosUmdDeviceDdi::DdiCreateRasterizerState( D3D10DDI_HRASTERIZERSTATE hRasterizerState, D3D10DDI_HRTRASTERIZERSTATE hRTRasterizerState) { - RosUmdLogging::Call(__FUNCTION__); - RosUmdRasterizerState* pRasterizerState = new (hRasterizerState.pDrvPrivate) RosUmdRasterizerState(desc, hRTRasterizerState); pRasterizerState; // unused } @@ -539,8 +481,6 @@ void APIENTRY RosUmdDeviceDdi::DdiDestroyRasterizerState( D3D10DDI_HDEVICE hDevice, D3D10DDI_HRASTERIZERSTATE hRasterizerState) { - RosUmdLogging::Call(__FUNCTION__); - RosUmdDevice * pDevice = RosUmdDevice::CastFrom(hDevice); RosUmdRasterizerState * pRasterizerState = RosUmdRasterizerState::CastFrom(hRasterizerState); @@ -552,8 +492,6 @@ void APIENTRY RosUmdDeviceDdi::DdiSetRasterizerState( D3D10DDI_HDEVICE hDevice, D3D10DDI_HRASTERIZERSTATE hRasterizerState) { - RosUmdLogging::Call(__FUNCTION__); - RosUmdDevice * pDevice = RosUmdDevice::CastFrom(hDevice); RosUmdRasterizerState * pRasterizerState = RosUmdRasterizerState::CastFrom(hRasterizerState); pDevice->SetRasterizerState(pRasterizerState); @@ -566,8 +504,6 @@ void APIENTRY RosUmdDeviceDdi::DdiSetScissorRects( _In_ const D3D10_DDI_RECT *pRects ) { - RosUmdLogging::Call(__FUNCTION__); - RosUmdDevice * pDevice = RosUmdDevice::CastFrom(hDevice); pDevice->SetScissorRects(NumScissorRects, ClearScissorRects, pRects); } @@ -580,8 +516,6 @@ SIZE_T APIENTRY RosUmdDeviceDdi::DdiCalcPrivateDepthStencilStateSize( D3D10DDI_HDEVICE hDevice, const D3D10_DDI_DEPTH_STENCIL_DESC* desc) { - RosUmdLogging::Call(__FUNCTION__); - RosUmdDevice * pDevice = RosUmdDevice::CastFrom(hDevice); pDevice; // unused desc; // unused @@ -595,8 +529,6 @@ void APIENTRY RosUmdDeviceDdi::DdiCreateDepthStencilState( D3D10DDI_HDEPTHSTENCILSTATE hDepthStencilState, D3D10DDI_HRTDEPTHSTENCILSTATE hRTDepthStencilState) { - RosUmdLogging::Call(__FUNCTION__); - RosUmdDevice * pDevice = RosUmdDevice::CastFrom(hDevice); pDevice; // unused @@ -608,8 +540,6 @@ void APIENTRY RosUmdDeviceDdi::DdiDestroyDepthStencilState( D3D10DDI_HDEVICE hDevice, D3D10DDI_HDEPTHSTENCILSTATE hDepthStencilState) { - RosUmdLogging::Call(__FUNCTION__); - RosUmdDevice * pDevice = RosUmdDevice::CastFrom(hDevice); RosUmdDepthStencilState * pDepthStencilState = RosUmdDepthStencilState::CastFrom(hDepthStencilState); @@ -623,8 +553,6 @@ void APIENTRY RosUmdDeviceDdi::DdiSetDepthStencilState( D3D10DDI_HDEPTHSTENCILSTATE hDepthStencilState, UINT StencilRef) { - RosUmdLogging::Call(__FUNCTION__); - RosUmdDevice * pDevice = RosUmdDevice::CastFrom(hDevice); RosUmdDepthStencilState * pDepthStencilState = RosUmdDepthStencilState::CastFrom(hDepthStencilState); pDevice->SetDepthStencilState(pDepthStencilState, StencilRef); @@ -638,8 +566,6 @@ SIZE_T APIENTRY RosUmdDeviceDdi::DdiCalcPrivateSamplerSize( D3D10DDI_HDEVICE hDevice, const D3D10_DDI_SAMPLER_DESC* desc) { - RosUmdLogging::Call(__FUNCTION__); - RosUmdDevice * pDevice = RosUmdDevice::CastFrom(hDevice); pDevice; // unused desc; // unused @@ -653,8 +579,6 @@ void APIENTRY RosUmdDeviceDdi::DdiCreateSampler( D3D10DDI_HSAMPLER hSampler, D3D10DDI_HRTSAMPLER hRTSampler) { - RosUmdLogging::Call(__FUNCTION__); - RosUmdDevice * pDevice = RosUmdDevice::CastFrom(hDevice); pDevice; // unusd @@ -666,8 +590,6 @@ void APIENTRY RosUmdDeviceDdi::DdiDestroySampler( D3D10DDI_HDEVICE hDevice, D3D10DDI_HSAMPLER hSampler) { - RosUmdLogging::Call(__FUNCTION__); - RosUmdDevice * pDevice = RosUmdDevice::CastFrom(hDevice); pDevice; // unusd @@ -681,8 +603,6 @@ void APIENTRY RosUmdDeviceDdi::DdiPSSetSamplers( UINT NumSamplers, const D3D10DDI_HSAMPLER* phSamplers) { - RosUmdLogging::Call(__FUNCTION__); - RosUmdDevice * pDevice = RosUmdDevice::CastFrom(hDevice); pDevice->SetPixelSamplers(Offset, NumSamplers, phSamplers); } @@ -693,8 +613,6 @@ void APIENTRY RosUmdDeviceDdi::DdiVSSetSamplers( UINT NumSamplers, const D3D10DDI_HSAMPLER* phSamplers) { - RosUmdLogging::Call(__FUNCTION__); - RosUmdDevice * pDevice = RosUmdDevice::CastFrom(hDevice); pDevice->SetVertexSamplers(Offset, NumSamplers, phSamplers); } @@ -705,8 +623,6 @@ void APIENTRY RosUmdDeviceDdi::DdiGSSetSamplers( UINT NumSamplers, const D3D10DDI_HSAMPLER* phSamplers) { - RosUmdLogging::Call(__FUNCTION__); - RosUmdDevice * pDevice = RosUmdDevice::CastFrom(hDevice); pDevice->SetGeometrySamplers(Offset, NumSamplers, phSamplers); } @@ -717,8 +633,6 @@ void APIENTRY RosUmdDeviceDdi::DdiCSSetSamplers( UINT NumSamplers, const D3D10DDI_HSAMPLER* phSamplers) { - RosUmdLogging::Call(__FUNCTION__); - RosUmdDevice * pDevice = RosUmdDevice::CastFrom(hDevice); pDevice->SetComputeSamplers(Offset, NumSamplers, phSamplers); } @@ -729,8 +643,6 @@ void APIENTRY RosUmdDeviceDdi::DdiHSSetSamplers( UINT NumSamplers, const D3D10DDI_HSAMPLER* phSamplers) { - RosUmdLogging::Call(__FUNCTION__); - RosUmdDevice * pDevice = RosUmdDevice::CastFrom(hDevice); pDevice->SetHullSamplers(Offset, NumSamplers, phSamplers); } @@ -741,8 +653,6 @@ void APIENTRY RosUmdDeviceDdi::DdiDSSetSamplers( UINT NumSamplers, const D3D10DDI_HSAMPLER* phSamplers) { - RosUmdLogging::Call(__FUNCTION__); - RosUmdDevice * pDevice = RosUmdDevice::CastFrom(hDevice); pDevice->SetDomainSamplers(Offset, NumSamplers, phSamplers); } @@ -755,8 +665,6 @@ SIZE_T APIENTRY RosUmdDeviceDdi::DdiCalcPrivateElementLayoutSize( D3D10DDI_HDEVICE hDevice, const D3D10DDIARG_CREATEELEMENTLAYOUT* pCreate) { - RosUmdLogging::Call(__FUNCTION__); - RosUmdDevice * pDevice = RosUmdDevice::CastFrom(hDevice); pDevice; // unused pCreate; // unused @@ -770,8 +678,6 @@ void APIENTRY RosUmdDeviceDdi::DdiCreateElementLayout( D3D10DDI_HELEMENTLAYOUT hElementLayout, D3D10DDI_HRTELEMENTLAYOUT hRTElementLayout) { - RosUmdLogging::Call(__FUNCTION__); - RosUmdDevice * pDevice = RosUmdDevice::CastFrom(hDevice); pDevice; // unused @@ -783,8 +689,6 @@ void APIENTRY RosUmdDeviceDdi::DdiDestroyElementLayout( D3D10DDI_HDEVICE hDevice, D3D10DDI_HELEMENTLAYOUT hElementLayout) { - RosUmdLogging::Call(__FUNCTION__); - RosUmdDevice * pDevice = RosUmdDevice::CastFrom(hDevice); pDevice; // unused @@ -801,8 +705,6 @@ void APIENTRY RosUmdDeviceDdi::DdiPsSetConstantBuffers11_1( const UINT* pFirstConstant, const UINT* pNumConstants) { - RosUmdLogging::Call(__FUNCTION__); - RosUmdDevice * pDevice = RosUmdDevice::CastFrom(hDevice); pDevice->PsSetConstantBuffers11_1(offset, numBuffers, phBuffers, pFirstConstant, pNumConstants); @@ -811,8 +713,6 @@ void APIENTRY RosUmdDeviceDdi::DdiIaSetInputLayout( D3D10DDI_HDEVICE hDevice, D3D10DDI_HELEMENTLAYOUT hElementLayout) { - RosUmdLogging::Call(__FUNCTION__); - RosUmdDevice * pDevice = RosUmdDevice::CastFrom(hDevice); RosUmdElementLayout * pElementLayout = RosUmdElementLayout::CastFrom(hElementLayout); pDevice->SetElementLayout(pElementLayout); @@ -827,8 +727,6 @@ SIZE_T APIENTRY RosUmdDeviceDdi::DdiCalcPrivateShaderSize( const UINT* pCode, const D3D11_1DDIARG_STAGE_IO_SIGNATURES* pSignatures) { - RosUmdLogging::Call(__FUNCTION__); - RosUmdDevice * pDevice = RosUmdDevice::CastFrom(hDevice); pDevice; // unused pCode; // unused @@ -844,8 +742,6 @@ void APIENTRY RosUmdDeviceDdi::DdiCreatePixelShader( D3D10DDI_HRTSHADER hRTShader, const D3D11_1DDIARG_STAGE_IO_SIGNATURES* pSignatures) { - RosUmdLogging::Entry(__FUNCTION__); - RosUmdDevice * pRosUmdDevice = RosUmdDevice::CastFrom(hDevice); try @@ -857,8 +753,6 @@ void APIENTRY RosUmdDeviceDdi::DdiCreatePixelShader( { pRosUmdDevice->SetException(e); } - - RosUmdLogging::Exit(__FUNCTION__); } void APIENTRY RosUmdDeviceDdi::DdiCreateVertexShader( @@ -868,8 +762,6 @@ void APIENTRY RosUmdDeviceDdi::DdiCreateVertexShader( D3D10DDI_HRTSHADER hRTShader, const D3D11_1DDIARG_STAGE_IO_SIGNATURES* pSignatures) { - RosUmdLogging::Entry(__FUNCTION__); - RosUmdDevice * pRosUmdDevice = RosUmdDevice::CastFrom(hDevice); try @@ -881,8 +773,6 @@ void APIENTRY RosUmdDeviceDdi::DdiCreateVertexShader( { pRosUmdDevice->SetException(e); } - - RosUmdLogging::Exit(__FUNCTION__); } void APIENTRY RosUmdDeviceDdi::DdiCreateGeometryShader( @@ -892,8 +782,6 @@ void APIENTRY RosUmdDeviceDdi::DdiCreateGeometryShader( D3D10DDI_HRTSHADER hRTShader, const D3D11_1DDIARG_STAGE_IO_SIGNATURES* pSignatures) { - RosUmdLogging::Entry(__FUNCTION__); - RosUmdDevice * pRosUmdDevice = RosUmdDevice::CastFrom(hDevice); try @@ -905,8 +793,6 @@ void APIENTRY RosUmdDeviceDdi::DdiCreateGeometryShader( { pRosUmdDevice->SetException(e); } - - RosUmdLogging::Exit(__FUNCTION__); } void APIENTRY RosUmdDeviceDdi::DdiCreateComputeShader( @@ -915,8 +801,6 @@ void APIENTRY RosUmdDeviceDdi::DdiCreateComputeShader( D3D10DDI_HSHADER hShader, D3D10DDI_HRTSHADER hRTShader) { - RosUmdLogging::Entry(__FUNCTION__); - RosUmdDevice * pRosUmdDevice = RosUmdDevice::CastFrom(hDevice); try @@ -928,8 +812,6 @@ void APIENTRY RosUmdDeviceDdi::DdiCreateComputeShader( { pRosUmdDevice->SetException(e); } - - RosUmdLogging::Exit(__FUNCTION__); } SIZE_T APIENTRY RosUmdDeviceDdi::DdiCalcPrivateTessellationShaderSize( @@ -937,8 +819,6 @@ SIZE_T APIENTRY RosUmdDeviceDdi::DdiCalcPrivateTessellationShaderSize( const UINT* pCode, const D3D11_1DDIARG_TESSELLATION_IO_SIGNATURES* pSignatures) { - RosUmdLogging::Call(__FUNCTION__); - RosUmdDevice * pDevice = RosUmdDevice::CastFrom(hDevice); pDevice; // unused @@ -955,8 +835,6 @@ void APIENTRY RosUmdDeviceDdi::DdiCreateHullShader( D3D10DDI_HRTSHADER hRTShader, const D3D11_1DDIARG_TESSELLATION_IO_SIGNATURES* pSignatures) { - RosUmdLogging::Entry(__FUNCTION__); - RosUmdDevice * pRosUmdDevice = RosUmdDevice::CastFrom(hDevice); try @@ -968,8 +846,6 @@ void APIENTRY RosUmdDeviceDdi::DdiCreateHullShader( { pRosUmdDevice->SetException(e); } - - RosUmdLogging::Exit(__FUNCTION__); } void APIENTRY RosUmdDeviceDdi::DdiCreateDomainShader( @@ -979,8 +855,6 @@ void APIENTRY RosUmdDeviceDdi::DdiCreateDomainShader( D3D10DDI_HRTSHADER hRTShader, const D3D11_1DDIARG_TESSELLATION_IO_SIGNATURES* pSignatures) { - RosUmdLogging::Entry(__FUNCTION__); - RosUmdDevice * pRosUmdDevice = RosUmdDevice::CastFrom(hDevice); try @@ -992,16 +866,12 @@ void APIENTRY RosUmdDeviceDdi::DdiCreateDomainShader( { pRosUmdDevice->SetException(e); } - - RosUmdLogging::Exit(__FUNCTION__); } void APIENTRY RosUmdDeviceDdi::DdiDestroyShader( D3D10DDI_HDEVICE hDevice, D3D10DDI_HSHADER hShader) { - RosUmdLogging::Call(__FUNCTION__); - RosUmdDevice * pDevice = RosUmdDevice::CastFrom(hDevice); pDevice->DestroyShader(hShader); @@ -1013,16 +883,13 @@ void APIENTRY RosUmdDeviceDdi::DdiPSSetShaderResources( UINT numViews, const D3D10DDI_HSHADERRESOURCEVIEW* pShaderResourceViews) { - RosUmdLogging::Call(__FUNCTION__); - RosUmdDevice * pDevice = RosUmdDevice::CastFrom(hDevice); pDevice->PSSetShaderResources(offset, numViews, pShaderResourceViews); } -void APIENTRY RosUmdDeviceDdi::DdiPsSetShader(D3D10DDI_HDEVICE hDevice, D3D10DDI_HSHADER hShader) { - RosUmdLogging::Call(__FUNCTION__); - +void APIENTRY RosUmdDeviceDdi::DdiPsSetShader(D3D10DDI_HDEVICE hDevice, D3D10DDI_HSHADER hShader) +{ RosUmdDevice * pDevice = RosUmdDevice::CastFrom(hDevice); RosUmdShader * pShader = RosUmdShader::CastFrom(hShader); pDevice->SetPixelShader(pShader); @@ -1030,8 +897,6 @@ void APIENTRY RosUmdDeviceDdi::DdiPsSetShader(D3D10DDI_HDEVICE hDevice, D3D10DDI void APIENTRY RosUmdDeviceDdi::DdiVsSetShader(D3D10DDI_HDEVICE hDevice, D3D10DDI_HSHADER hShader) { - RosUmdLogging::Call(__FUNCTION__); - RosUmdDevice * pDevice = RosUmdDevice::CastFrom(hDevice); RosUmdShader * pShader = RosUmdShader::CastFrom(hShader); pDevice->SetVertexShader(pShader); @@ -1039,8 +904,6 @@ void APIENTRY RosUmdDeviceDdi::DdiVsSetShader(D3D10DDI_HDEVICE hDevice, D3D10DDI void APIENTRY RosUmdDeviceDdi::DdiGsSetShader(D3D10DDI_HDEVICE hDevice, D3D10DDI_HSHADER hShader) { - RosUmdLogging::Call(__FUNCTION__); - RosUmdDevice * pDevice = RosUmdDevice::CastFrom(hDevice); RosUmdShader * pShader = RosUmdShader::CastFrom(hShader); pDevice->SetGeometryShader(pShader); @@ -1048,8 +911,6 @@ void APIENTRY RosUmdDeviceDdi::DdiGsSetShader(D3D10DDI_HDEVICE hDevice, D3D10DDI void APIENTRY RosUmdDeviceDdi::DdiHsSetShader(D3D10DDI_HDEVICE hDevice, D3D10DDI_HSHADER hShader) { - RosUmdLogging::Call(__FUNCTION__); - RosUmdDevice * pDevice = RosUmdDevice::CastFrom(hDevice); RosUmdShader * pShader = RosUmdShader::CastFrom(hShader); pDevice->SetHullShader(pShader); @@ -1057,8 +918,6 @@ void APIENTRY RosUmdDeviceDdi::DdiHsSetShader(D3D10DDI_HDEVICE hDevice, D3D10DDI void APIENTRY RosUmdDeviceDdi::DdiDsSetShader(D3D10DDI_HDEVICE hDevice, D3D10DDI_HSHADER hShader) { - RosUmdLogging::Call(__FUNCTION__); - RosUmdDevice * pDevice = RosUmdDevice::CastFrom(hDevice); RosUmdShader * pShader = RosUmdShader::CastFrom(hShader); pDevice->SetDomainShader(pShader); @@ -1066,8 +925,6 @@ void APIENTRY RosUmdDeviceDdi::DdiDsSetShader(D3D10DDI_HDEVICE hDevice, D3D10DDI void APIENTRY RosUmdDeviceDdi::DdiCsSetShader(D3D10DDI_HDEVICE hDevice, D3D10DDI_HSHADER hShader) { - RosUmdLogging::Call(__FUNCTION__); - RosUmdDevice * pDevice = RosUmdDevice::CastFrom(hDevice); RosUmdShader * pShader = RosUmdShader::CastFrom(hShader); @@ -1082,8 +939,6 @@ SIZE_T APIENTRY RosUmdDeviceDdi::DdiCalcPrivateBlendStateSize( D3D10DDI_HDEVICE hDevice, const D3D11_1_DDI_BLEND_DESC* desc) { - RosUmdLogging::Call(__FUNCTION__); - RosUmdDevice * pDevice = RosUmdDevice::CastFrom(hDevice); pDevice; // unused desc; // unused @@ -1097,8 +952,6 @@ void APIENTRY RosUmdDeviceDdi::DdiCreateBlendState( D3D10DDI_HBLENDSTATE hBlendState, D3D10DDI_HRTBLENDSTATE hRTBlendState) { - RosUmdLogging::Call(__FUNCTION__); - RosUmdDevice * pDevice = RosUmdDevice::CastFrom(hDevice); pDevice; // unused @@ -1111,8 +964,6 @@ void APIENTRY RosUmdDeviceDdi::DdiDestroyBlendState( D3D10DDI_HDEVICE hDevice, D3D10DDI_HBLENDSTATE hBlendState) { - RosUmdLogging::Call(__FUNCTION__); - RosUmdDevice * pDevice = RosUmdDevice::CastFrom(hDevice); pDevice; // unused @@ -1126,8 +977,6 @@ void APIENTRY RosUmdDeviceDdi::DdiSetBlendState( const FLOAT pBlendFactor[4], UINT sampleMask) { - RosUmdLogging::Call(__FUNCTION__); - RosUmdDevice * pDevice = RosUmdDevice::CastFrom(hDevice); RosUmdBlendState * pBlendState = RosUmdBlendState::CastFrom(hBlendState); pDevice->SetBlendState(pBlendState, pBlendFactor, sampleMask); @@ -1178,8 +1027,6 @@ SIZE_T APIENTRY RosUmdDeviceDdi::DdiCalcPrivateDepthStencilViewSize11( D3D10DDI_HDEVICE, const D3D11DDIARG_CREATEDEPTHSTENCILVIEW*) { - RosUmdLogging::Call(__FUNCTION__); - return sizeof(RosUmdDepthStencilView); } @@ -1189,8 +1036,6 @@ void APIENTRY RosUmdDeviceDdi::DdiCreateDepthStencilView11( D3D10DDI_HDEPTHSTENCILVIEW hDepthStencilView, D3D10DDI_HRTDEPTHSTENCILVIEW hRTDepthStencilView) { - RosUmdLogging::Call(__FUNCTION__); - RosUmdDepthStencilView * pDepthStencilView = new(hDepthStencilView.pDrvPrivate) RosUmdDepthStencilView(pCreate, hRTDepthStencilView); pDepthStencilView; // unused } @@ -1199,8 +1044,6 @@ void APIENTRY RosUmdDeviceDdi::DdiDestroyDepthStencilView( D3D10DDI_HDEVICE, D3D10DDI_HDEPTHSTENCILVIEW hDepthStencilView) { - RosUmdLogging::Call(__FUNCTION__); - RosUmdDepthStencilView * pDepthStencilView = RosUmdDepthStencilView::CastFrom(hDepthStencilView); pDepthStencilView->~RosUmdDepthStencilView(); } @@ -1222,8 +1065,6 @@ void APIENTRY RosUmdDeviceDdi::DdiClearDepthStencilView( FLOAT depthValue, UINT8 stencilValue) { - RosUmdLogging::Call(__FUNCTION__); - RosUmdDevice * pDevice = RosUmdDevice::CastFrom(hDevice); RosUmdDepthStencilView * pDepthStencilView = RosUmdDepthStencilView::CastFrom(hDepthStencilView); @@ -1310,8 +1151,6 @@ void APIENTRY RosUmdDeviceDdi::DdiIaSetVertexBuffers( const UINT* pStrides, const UINT* pOffsets) { - RosUmdLogging::Call(__FUNCTION__); - RosUmdDevice * pDevice = RosUmdDevice::CastFrom(hDevice); pDevice->SetVertexBuffers(startBuffer, numBuffers, phBuffers, pStrides, pOffsets); } @@ -1326,8 +1165,6 @@ void APIENTRY RosUmdDeviceDdi::DdiIaSetIndexBuffer( DXGI_FORMAT hIndexFormat, UINT offset) { - RosUmdLogging::Call(__FUNCTION__); - RosUmdDevice * pDevice = RosUmdDevice::CastFrom(hDevice); pDevice->SetIndexBuffer(hIndexBuffer, hIndexFormat, offset); } @@ -1340,8 +1177,6 @@ void APIENTRY RosUmdDeviceDdi::DdiDynamicIABufferMapNoOverwrite( UINT mapFlags, D3D10DDI_MAPPED_SUBRESOURCE* pMappedSubRes) { - RosUmdLogging::Entry(__FUNCTION__); - RosUmdDevice* pRosUmdDevice = RosUmdDevice::CastFrom(hDevice); RosUmdResource * pResource = (RosUmdResource *)hResource.pDrvPrivate; @@ -1354,8 +1189,6 @@ void APIENTRY RosUmdDeviceDdi::DdiDynamicIABufferMapNoOverwrite( { pRosUmdDevice->SetException(e); } - - RosUmdLogging::Exit(__FUNCTION__); } void APIENTRY RosUmdDeviceDdi::DdiDynamicIABufferMapDiscard( @@ -1366,8 +1199,6 @@ void APIENTRY RosUmdDeviceDdi::DdiDynamicIABufferMapDiscard( UINT mapFlags, D3D10DDI_MAPPED_SUBRESOURCE* pMappedSubRes) { - RosUmdLogging::Entry(__FUNCTION__); - RosUmdDevice* pRosUmdDevice = RosUmdDevice::CastFrom(hDevice); RosUmdResource * pResource = (RosUmdResource *)hResource.pDrvPrivate; @@ -1380,8 +1211,6 @@ void APIENTRY RosUmdDeviceDdi::DdiDynamicIABufferMapDiscard( { pRosUmdDevice->SetException(e); } - - RosUmdLogging::Exit(__FUNCTION__); } void APIENTRY RosUmdDeviceDdi::DdiDynamicIABufferUnmap( @@ -1389,8 +1218,6 @@ void APIENTRY RosUmdDeviceDdi::DdiDynamicIABufferUnmap( D3D10DDI_HRESOURCE hResource, UINT subResource) { - RosUmdLogging::Entry(__FUNCTION__); - RosUmdDevice* pRosUmdDevice = RosUmdDevice::CastFrom(hDevice); RosUmdResource * pResource = (RosUmdResource *)hResource.pDrvPrivate; @@ -1403,8 +1230,6 @@ void APIENTRY RosUmdDeviceDdi::DdiDynamicIABufferUnmap( { pRosUmdDevice->SetException(e); } - - RosUmdLogging::Exit(__FUNCTION__); } void APIENTRY RosUmdDeviceDdi::DdiVsSetConstantBuffers11_1( @@ -1415,8 +1240,6 @@ void APIENTRY RosUmdDeviceDdi::DdiVsSetConstantBuffers11_1( const UINT * pFirstConstant, const UINT * pNumberConstants) { - RosUmdLogging::Call(__FUNCTION__); - RosUmdDevice * pDevice = RosUmdDevice::CastFrom(hDevice); pDevice->VsSetConstantBuffers11_1(startBuffer, numberBuffers, phResources, pFirstConstant, pNumberConstants); @@ -1430,8 +1253,6 @@ void APIENTRY RosUmdDeviceDdi::DdiDynamicConstantBufferMapDiscard( UINT mapFlags, D3D10DDI_MAPPED_SUBRESOURCE* pMappedSubRes) { - RosUmdLogging::Entry(__FUNCTION__); - RosUmdDevice* pRosUmdDevice = RosUmdDevice::CastFrom(hDevice); RosUmdResource * pResource = (RosUmdResource *)hResource.pDrvPrivate; @@ -1444,8 +1265,6 @@ void APIENTRY RosUmdDeviceDdi::DdiDynamicConstantBufferMapDiscard( { pRosUmdDevice->SetException(e); } - - RosUmdLogging::Exit(__FUNCTION__); } void APIENTRY RosUmdDeviceDdi::DdiDynamicConstantBufferUnmap( @@ -1453,8 +1272,6 @@ void APIENTRY RosUmdDeviceDdi::DdiDynamicConstantBufferUnmap( D3D10DDI_HRESOURCE hResource, UINT subResource) { - RosUmdLogging::Entry(__FUNCTION__); - RosUmdDevice* pRosUmdDevice = RosUmdDevice::CastFrom(hDevice); RosUmdResource * pResource = (RosUmdResource *)hResource.pDrvPrivate; @@ -1467,14 +1284,10 @@ void APIENTRY RosUmdDeviceDdi::DdiDynamicConstantBufferUnmap( { pRosUmdDevice->SetException(e); } - - RosUmdLogging::Exit(__FUNCTION__); } HRESULT RosUmdDeviceDdi::Present(DXGI_DDI_ARG_PRESENT* pPresentData) { - RosUmdLogging::Entry(__FUNCTION__); - RosUmdDevice* pRosUmdDevice = RosUmdDevice::CastFrom(pPresentData->hDevice); HRESULT hr = pRosUmdDevice->Present(pPresentData); if (FAILED(hr)) @@ -1482,31 +1295,25 @@ HRESULT RosUmdDeviceDdi::Present(DXGI_DDI_ARG_PRESENT* pPresentData) pRosUmdDevice->SetError(hr); } - RosUmdLogging::Exit(__FUNCTION__); return hr; } HRESULT RosUmdDeviceDdi::RotateResourceIdentities( DXGI_DDI_ARG_ROTATE_RESOURCE_IDENTITIES* Args) { - RosUmdLogging::Entry(__FUNCTION__); - RosUmdDevice* pRosUmdDevice = RosUmdDevice::CastFrom(Args->hDevice); HRESULT hr = pRosUmdDevice->RotateResourceIdentities(Args); if (FAILED(hr)) { pRosUmdDevice->SetError(hr); } - - RosUmdLogging::Exit(__FUNCTION__); + return hr; } HRESULT RosUmdDeviceDdi::SetDisplayMode( DXGI_DDI_ARG_SETDISPLAYMODE* pDisplayModeData) { - RosUmdLogging::Entry(__FUNCTION__); - RosUmdDevice* pRosUmdDevice = RosUmdDevice::CastFrom(pDisplayModeData->hDevice); HRESULT hr = pRosUmdDevice->SetDisplayMode(pDisplayModeData); if (FAILED(hr)) @@ -1514,14 +1321,11 @@ HRESULT RosUmdDeviceDdi::SetDisplayMode( pRosUmdDevice->SetError(hr); } - RosUmdLogging::Exit(__FUNCTION__); return hr; } HRESULT RosUmdDeviceDdi::Present1(DXGI_DDI_ARG_PRESENT1* pPresentData) { - RosUmdLogging::Entry(__FUNCTION__); - RosUmdDevice* pRosUmdDevice = RosUmdDevice::CastFrom(pPresentData->hDevice); HRESULT hr = pRosUmdDevice->Present1(pPresentData); if (FAILED(hr)) @@ -1529,7 +1333,6 @@ HRESULT RosUmdDeviceDdi::Present1(DXGI_DDI_ARG_PRESENT1* pPresentData) pRosUmdDevice->SetError(hr); } - RosUmdLogging::Exit(__FUNCTION__); return hr; } @@ -1542,8 +1345,6 @@ void RosUmdDeviceDdi::CheckDirectFlipSupport( BOOL *pSupported ) { - RosUmdLogging::Entry(__FUNCTION__); - RosUmdDevice* pRosUmdDevice = RosUmdDevice::CastFrom(hDevice); pRosUmdDevice->CheckDirectFlipSupport( hDevice, @@ -1551,6 +1352,65 @@ void RosUmdDeviceDdi::CheckDirectFlipSupport( hResource2, CheckDirectFlipFlags, pSupported); +} + +void APIENTRY RosUmdDeviceDdi::DdiSetPredication( + D3D10DDI_HDEVICE hDevice, + D3D10DDI_HQUERY hQuery, + BOOL bPredicateValue + ) +{ + RosUmdDevice* pRosUmdDevice = RosUmdDevice::CastFrom(hDevice); + + try + { + pRosUmdDevice->SetPredication(hQuery, bPredicateValue); + } + catch (std::exception & e) + { + pRosUmdDevice->SetException(e); + } +} - RosUmdLogging::Exit(__FUNCTION__); +void APIENTRY RosUmdDeviceDdi::DdiResourceCopyRegion11_1( + D3D10DDI_HDEVICE hDevice, + D3D10DDI_HRESOURCE hDstResource, + UINT DstSubresource, + UINT DstX, + UINT DstY, + UINT DstZ, + D3D10DDI_HRESOURCE hSrcResource, + UINT SrcSubresource, + const D3D10_DDI_BOX* pSrcBox, + UINT copyFlags + ) +{ + RosUmdDevice* pRosUmdDevice = RosUmdDevice::CastFrom(hDevice); + RosUmdResource * pDestinationResource = (RosUmdResource *) hDstResource.pDrvPrivate; + RosUmdResource * pSourceResource = (RosUmdResource *) hSrcResource.pDrvPrivate; + + try + { + pRosUmdDevice->ResourceCopyRegion11_1(pDestinationResource, DstSubresource, DstX, DstY, DstZ, pSourceResource, SrcSubresource, pSrcBox, copyFlags); + } + + catch (std::exception & e) + { + pRosUmdDevice->SetException(e); + } +} + +void APIENTRY RosUmdDeviceDdi::DdiResourceCopyRegion( + D3D10DDI_HDEVICE hDevice, + D3D10DDI_HRESOURCE hDstResource, + UINT DstSubresource, + UINT DstX, + UINT DstY, + UINT DstZ, + D3D10DDI_HRESOURCE hSrcResource, + UINT SrcSubresource, + const D3D10_DDI_BOX* pSrcBox + ) +{ + DdiResourceCopyRegion11_1(hDevice, hDstResource, DstSubresource, DstX, DstY, DstZ, hSrcResource, SrcSubresource, pSrcBox, 0); } \ No newline at end of file diff --git a/render-only-sample/rosumd/RosUmdDeviceDdi.h b/render-only-sample/rosumd/RosUmdDeviceDdi.h index 6de00e4..51648b7 100644 --- a/render-only-sample/rosumd/RosUmdDeviceDdi.h +++ b/render-only-sample/rosumd/RosUmdDeviceDdi.h @@ -7,8 +7,6 @@ //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// #pragma once -#include "d3dumddi_.h" - #include "RosUmdLogging.h" class RosUmdDeviceDdi @@ -63,7 +61,7 @@ class RosUmdDeviceDdi static void APIENTRY DdiSetViewports(D3D10DDI_HDEVICE, UINT, UINT, const D3D10_DDI_VIEWPORT*); static void APIENTRY DdiIaSetTopology(D3D10DDI_HDEVICE, D3D10_DDI_PRIMITIVE_TOPOLOGY); - static void APIENTRY SetPredication_Default(D3D10DDI_HDEVICE, D3D10DDI_HQUERY, BOOL) { RosUmdLogging::Call(__FUNCTION__); __debugbreak(); } + static void APIENTRY DdiSetPredication(D3D10DDI_HDEVICE, D3D10DDI_HQUERY, BOOL); static void APIENTRY SetTextFilter_Default(D3D10DDI_HDEVICE, UINT, UINT) { RosUmdLogging::Call(__FUNCTION__); __debugbreak(); } static void APIENTRY ClearUnorderedAccessViewUint_Default(D3D10DDI_HDEVICE, D3D11DDI_HUNORDEREDACCESSVIEW, const UINT[4]) { RosUmdLogging::Call(__FUNCTION__); __debugbreak(); } static void APIENTRY ClearUnorderedAccessViewFloat_Default(D3D10DDI_HDEVICE, D3D11DDI_HUNORDEREDACCESSVIEW, const FLOAT[4]) { RosUmdLogging::Call(__FUNCTION__); __debugbreak(); } @@ -92,8 +90,8 @@ class RosUmdDeviceDdi static void APIENTRY ShaderResourceViewReadAfterWriteHazard_Default(D3D10DDI_HDEVICE, D3D10DDI_HSHADERRESOURCEVIEW, D3D10DDI_HRESOURCE) { RosUmdLogging::Call(__FUNCTION__); __debugbreak(); } static void APIENTRY ResourceReadAfterWriteHazard_Default(D3D10DDI_HDEVICE, D3D10DDI_HRESOURCE) { RosUmdLogging::Call(__FUNCTION__); __debugbreak(); } static void APIENTRY ResourceWriteAfterWriteHazard_Default(D3D10DDI_HDEVICE, D3D10DDI_HRESOURCE) { RosUmdLogging::Call(__FUNCTION__); __debugbreak(); } - static void APIENTRY ResourceCopyRegion_Default(D3D10DDI_HDEVICE, D3D10DDI_HRESOURCE, UINT, UINT, UINT, UINT, D3D10DDI_HRESOURCE, UINT, const D3D10_DDI_BOX*) { RosUmdLogging::Call(__FUNCTION__); __debugbreak(); } - static void APIENTRY ResourceCopyRegion11_1_Default(D3D10DDI_HDEVICE, D3D10DDI_HRESOURCE, UINT, UINT, UINT, UINT, D3D10DDI_HRESOURCE, UINT, const D3D10_DDI_BOX*, UINT) { RosUmdLogging::Call(__FUNCTION__); __debugbreak(); } + static void APIENTRY DdiResourceCopyRegion(D3D10DDI_HDEVICE, D3D10DDI_HRESOURCE, UINT, UINT, UINT, UINT, D3D10DDI_HRESOURCE, UINT, const D3D10_DDI_BOX*); + static void APIENTRY DdiResourceCopyRegion11_1(D3D10DDI_HDEVICE, D3D10DDI_HRESOURCE, UINT, UINT, UINT, UINT, D3D10DDI_HRESOURCE, UINT, const D3D10_DDI_BOX*, UINT); static void APIENTRY DdiResourceCopy(D3D10DDI_HDEVICE, D3D10DDI_HRESOURCE, D3D10DDI_HRESOURCE); static void APIENTRY ResourceResolveSubresource_Default(D3D10DDI_HDEVICE, D3D10DDI_HRESOURCE, UINT, D3D10DDI_HRESOURCE, UINT, DXGI_FORMAT) { RosUmdLogging::Call(__FUNCTION__); __debugbreak(); } static void APIENTRY DefaultConstantBufferUpdateSubresourceUP_Default(D3D10DDI_HDEVICE, D3D10DDI_HRESOURCE, UINT, const D3D10_DDI_BOX*, const VOID*, UINT, UINT) { RosUmdLogging::Call(__FUNCTION__); __debugbreak(); } diff --git a/render-only-sample/rosumd/RosUmdElementLayout.h b/render-only-sample/rosumd/RosUmdElementLayout.h index 82d18d8..fa6a339 100644 --- a/render-only-sample/rosumd/RosUmdElementLayout.h +++ b/render-only-sample/rosumd/RosUmdElementLayout.h @@ -1,7 +1,5 @@ #pragma once -#include "d3dumddi_.h" - class RosUmdElementLayout { friend RosUmdDevice; diff --git a/render-only-sample/rosumd/RosUmdLogging.cpp b/render-only-sample/rosumd/RosUmdLogging.cpp new file mode 100644 index 0000000..3338907 --- /dev/null +++ b/render-only-sample/rosumd/RosUmdLogging.cpp @@ -0,0 +1,55 @@ +// +// Copyright (C) Microsoft. All rights reserved. +// + +#include "precomp.h" + +#include + +int _RosLogBugcheck ( + ULONG /*Level*/ + ) +{ + // Raise a noncontinuable exception + RaiseException( + DWORD(E_FAIL), // dwExceptionCode + EXCEPTION_NONCONTINUABLE, + 0, + nullptr); + + return 1; +} // _RosLogBugcheck (...) + +int _RosLogDebug ( + ULONG Level + ) +{ + static PCSTR levelDescriptions[] = { + "[%s]", // TRACE_LEVEL_NONE + "critical error", // TRACE_LEVEL_CRITICAL + "noncritical error", // TRACE_LEVEL_ERROR + "warning", // TRACE_LEVEL_WARNING + "information", // TRACE_LEVEL_INFORMATION + "trace" // TRACE_LEVEL_VERBOSE + }; // levelDescriptions + + volatile void* returnAddress = _ReturnAddress(); + volatile PCSTR levelDescriptionSz = + levelDescriptions[(Level < ARRAYSIZE(levelDescriptions)) ? Level : 0]; + char buf[64]; + HRESULT hr = StringCchPrintfA( + buf, + ARRAYSIZE(buf), + "\n*** ROSUMD %s detected @%p.\n", + levelDescriptionSz, + returnAddress); + + if (SUCCEEDED(hr)) { + OutputDebugStringA(buf); + } + + DbgRaiseAssertionFailure(); + + return 1; +} // _RosLogDebug (...) + diff --git a/render-only-sample/rosumd/RosUmdLogging.h b/render-only-sample/rosumd/RosUmdLogging.h index ffc9b67..420ca02 100644 --- a/render-only-sample/rosumd/RosUmdLogging.h +++ b/render-only-sample/rosumd/RosUmdLogging.h @@ -1,7 +1,23 @@ -#pragma once +#ifndef _ROSUMDLOGGING_H_ +#define _ROSUMDLOGGING_H_ -#include -#include +// +// Tracing GUID - D124564D-F51F-402D-A86E-7E2247D30AF3 +// +#define WPP_CONTROL_GUIDS \ + WPP_DEFINE_CONTROL_GUID(ROSUMD, (D124564D,F51F,402D,A86E,7E2247D30AF3), \ + WPP_DEFINE_BIT(ROS_TRACING_DEFAULT) \ + WPP_DEFINE_BIT(ROS_TRACING_PRESENT) \ + WPP_DEFINE_BIT(ROS_TRACING_VIDPN) \ + WPP_DEFINE_BIT(ROS_TRACING_DEBUG) \ + WPP_DEFINE_BIT(ROS_TRACING_BUGCHECK) \ + ) + +#define WPP_LEVEL_FLAGS_LOGGER(level,flags) WPP_LEVEL_LOGGER(flags) +#define WPP_LEVEL_FLAGS_ENABLED(level, flags) \ + (WPP_LEVEL_ENABLED(flags) && WPP_CONTROL(WPP_BIT_ ## flags).Level >= level) + +#include class RosUmdLogging { @@ -29,3 +45,5 @@ class RosUmdLogging } }; + +#endif // _ROSUMDLOGGING_H_ diff --git a/render-only-sample/rosumd/RosUmdRasterizerState.h b/render-only-sample/rosumd/RosUmdRasterizerState.h index acf29f9..1a777c3 100644 --- a/render-only-sample/rosumd/RosUmdRasterizerState.h +++ b/render-only-sample/rosumd/RosUmdRasterizerState.h @@ -1,7 +1,5 @@ #pragma once -#include "d3dumddi_.h" - class RosUmdRasterizerState { diff --git a/render-only-sample/rosumd/RosUmdRenderTargetView.h b/render-only-sample/rosumd/RosUmdRenderTargetView.h index 6079fbd..584eea8 100644 --- a/render-only-sample/rosumd/RosUmdRenderTargetView.h +++ b/render-only-sample/rosumd/RosUmdRenderTargetView.h @@ -1,7 +1,5 @@ #pragma once -#include "d3dumddi_.h" - class RosUmdRenderTargetView { friend class RosUmdDevice; diff --git a/render-only-sample/rosumd/RosUmdResource.cpp b/render-only-sample/rosumd/RosUmdResource.cpp index b0a6d47..661344c 100644 --- a/render-only-sample/rosumd/RosUmdResource.cpp +++ b/render-only-sample/rosumd/RosUmdResource.cpp @@ -5,10 +5,14 @@ // Copyright (C) Microsoft Corporation // //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#include "precomp.h" + +#include "RosUmdLogging.h" +#include "RosUmdResource.tmh" + #include "RosUmdDevice.h" #include "RosUmdResource.h" #include "RosUmdDebug.h" -#include "RosUmdLogging.h" #include "RosContext.h" @@ -18,7 +22,7 @@ RosUmdResource::RosUmdResource() : m_signature(_SIGNATURE::CONSTRUCTED), m_hKMAllocation(NULL) { - // do nothing + } RosUmdResource::~RosUmdResource() @@ -66,6 +70,8 @@ RosUmdResource::Standup( ZeroMemory(&m_primaryDesc, sizeof(m_primaryDesc)); } + memset(&m_TileInfo, 0, sizeof(m_TileInfo)); + CalculateMemoryLayout(); m_hRTResource = hRTResource; @@ -93,6 +99,24 @@ void RosUmdResource::InitSharedResourceFromExistingAllocation ( { assert(m_signature == _SIGNATURE::CONSTRUCTED); + ROS_LOG_TRACE( + "Opening existing resource. " + "(ExistingAllocationPtr->m_hwWidth/HeightPixels = %u,%u " + "ExistingAllocationPtr->m_hwPitchBytes = %u, " + "ExistingAllocationPtr->m_hwSizeBytes = %u, " + "ExistingAllocationPtr->m_isPrimary = %d, " + "hRTResource = 0x%p, " + "hKMResource= 0x%x, " + "hKMAllocation = 0x%x)", + ExistingAllocationPtr->m_hwWidthPixels, + ExistingAllocationPtr->m_hwHeightPixels, + ExistingAllocationPtr->m_hwPitchBytes, + ExistingAllocationPtr->m_hwSizeBytes, + ExistingAllocationPtr->m_isPrimary, + hRTResource.handle, + hKMResource.handle, + hKMAllocation); + // copy members from the existing allocation into this object RosAllocationExchange* basePtr = this; *basePtr = *ExistingAllocationPtr; @@ -100,6 +124,14 @@ void RosUmdResource::InitSharedResourceFromExistingAllocation ( // HW specific information calculated based on the fields above CalculateMemoryLayout(); + NT_ASSERT( + (m_hwLayout == ExistingAllocationPtr->m_hwLayout) && + (m_hwWidthPixels == ExistingAllocationPtr->m_hwWidthPixels) && + (m_hwHeightPixels == ExistingAllocationPtr->m_hwHeightPixels) && + (m_hwFormat == ExistingAllocationPtr->m_hwFormat) && + (m_hwPitchBytes == ExistingAllocationPtr->m_hwPitchBytes) && + (m_hwSizeBytes == ExistingAllocationPtr->m_hwSizeBytes)); + m_hRTResource = hRTResource; m_hKMResource = hKMResource.handle; m_hKMAllocation = hKMAllocation; @@ -262,6 +294,140 @@ RosUmdResource::Unmap( pUmdDevice->Unlock(&unlock); } +VC4TileInfo RosUmdResource::FillTileInfo(UINT bpp) +{ + // Provide detailed information about tile. + // Partial information about 4kB tiles, 1kB sub-tiles and micro-tiles for + // given bpp is precalculated. + // Values are used i.e. during converting bitmap to tiled texture + + VC4TileInfo info = { 0 }; + + if (bpp == 8) + { + info.VC4_1kBSubTileWidthPixels = VC4_1KB_SUB_TILE_WIDTH_8BPP; + info.VC4_1kBSubTileHeightPixels = VC4_1KB_SUB_TILE_HEIGHT_8BPP; + info.VC4_MicroTileWidthBytes = VC4_MICRO_TILE_WIDTH_BYTES_8BPP; + info.vC4_MicroTileHeight = VC4_MICRO_TILE_HEIGHT_8BPP; + } + else if (bpp == 16) + { + info.VC4_1kBSubTileWidthPixels = VC4_1KB_SUB_TILE_WIDTH_16BPP; + info.VC4_1kBSubTileHeightPixels = VC4_1KB_SUB_TILE_HEIGHT_16BPP; + info.VC4_MicroTileWidthBytes = VC4_MICRO_TILE_WIDTH_BYTES_16BPP; + info.vC4_MicroTileHeight = VC4_MICRO_TILE_HEIGHT_16BPP; + } + else if (bpp == 32) + { + info.VC4_1kBSubTileWidthPixels = VC4_1KB_SUB_TILE_WIDTH_32BPP; + info.VC4_1kBSubTileHeightPixels = VC4_1KB_SUB_TILE_HEIGHT_32BPP; + info.VC4_MicroTileWidthBytes = VC4_MICRO_TILE_WIDTH_BYTES_32BPP; + info.vC4_MicroTileHeight = VC4_MICRO_TILE_HEIGHT_32BPP; + } + else + { + // We expect 8, 16 or 32 bpp only + assert(false); + } + + // Calculate sub-tile width in bytes + info.VC4_1kBSubTileWidthBytes = info.VC4_1kBSubTileWidthPixels * (bpp / 8); + + // 4kB tile consists of four 1kB sub-tiles + info.VC4_4kBTileWidthPixels = info.VC4_1kBSubTileWidthPixels * 2; + info.VC4_4kBTileHeightPixels = info.VC4_1kBSubTileHeightPixels * 2; + info.VC4_4kBTileWidthBytes = info.VC4_1kBSubTileWidthBytes * 2; + + return info; +} + +void +RosUmdResource::MapDxgiFormatToInternalFormats(DXGI_FORMAT format, _Out_ UINT &bpp, _Out_ RosHwFormat &rosFormat) +{ + + // Number of HW formats is limited, so some of DXGI formats must be emulated. + // For example, format DXGI_FORMAT_R8_UNORM is emulated with DXGI_FORMAT_R8G8B8A8_UNORM + // where G8, B8 are set to 0 + // + switch (format) + { + case DXGI_FORMAT_R8G8B8A8_UNORM: + { + bpp = 32; + rosFormat = RosHwFormat::X8888; + } + break; + + case DXGI_FORMAT_R8G8_UNORM: + { + bpp = 32; + rosFormat = RosHwFormat::X8888; + } + break; + + case DXGI_FORMAT_R8_UNORM: + { + bpp = 32; + rosFormat = RosHwFormat::X8888; + } + break; + + case DXGI_FORMAT_A8_UNORM: + { + bpp = 8; + rosFormat = RosHwFormat::X8; + } + break; + + case DXGI_FORMAT_D24_UNORM_S8_UINT: + { + bpp = 8; + rosFormat = RosHwFormat::X8; + } + break; + + case DXGI_FORMAT_D16_UNORM: + { + bpp = 8; + rosFormat = RosHwFormat::X8; + } + break; + + default: + { + // Formats that are not on the list. + assert(false); + } + + } +} + +void +RosUmdResource::CalculateTilesInfo() +{ + UINT bpp = 0; + + // Provide information about hardware formats + MapDxgiFormatToInternalFormats(m_format, bpp, m_hwFormat); + + // Prepare information about tiles + m_TileInfo = FillTileInfo(bpp); + + m_hwWidthTilePixels = m_TileInfo.VC4_4kBTileWidthPixels; + m_hwHeightTilePixels = m_TileInfo.VC4_4kBTileHeightPixels; + + m_hwWidthTiles = (m_hwWidthPixels + m_hwWidthTilePixels - 1) / m_hwWidthTilePixels; + m_hwHeightTiles = (m_hwHeightPixels + m_hwHeightTilePixels - 1) / m_hwHeightTilePixels; + m_hwWidthPixels = m_hwWidthTiles*m_hwWidthTilePixels; + m_hwHeightPixels = m_hwHeightTiles*m_hwHeightTilePixels; + + UINT sizeTileBytes = m_hwWidthTilePixels * m_hwHeightTilePixels * (bpp/8); + + m_hwSizeBytes = m_hwWidthTiles * m_hwHeightTiles * sizeTileBytes; + m_hwPitchBytes = 0; + +} + void RosUmdResource::SetLockFlags( D3D10_DDI_MAP mapType, @@ -343,12 +509,14 @@ RosUmdResource::CalculateMemoryLayout( m_hwFormat = RosHwFormat::X8888; } + // Disable tiled format until issue #48 is fixed. + // // Force tiled layout for given configuration only - if ((m_usage == D3D10_DDI_USAGE_DEFAULT) && - (m_bindFlags == D3D10_DDI_BIND_SHADER_RESOURCE)) - { - m_hwLayout = RosHwLayout::Tiled; - } + // if ((m_usage == D3D10_DDI_USAGE_DEFAULT) && + // (m_bindFlags == D3D10_DDI_BIND_SHADER_RESOURCE)) + // { + // m_hwLayout = RosHwLayout::Tiled; + // } // Using system memory linear MipMap as example m_hwWidthPixels = m_mip0Info.TexelWidth; @@ -379,23 +547,7 @@ RosUmdResource::CalculateMemoryLayout( } else { - assert(m_hwLayout == RosHwLayout::Tiled); - assert(m_mipLevels == 1); - - assert((m_hwFormat == RosHwFormat::X8888) || (m_hwFormat == RosHwFormat::D24S8)); - - // Values are hardocded - we are using RosHwFormat::X8888 format - m_hwWidthTilePixels = VC4_4KB_TILE_WIDTH; - m_hwHeightTilePixels = VC4_4KB_TILE_HEIGHT; - m_hwWidthTiles = (m_hwWidthPixels + m_hwWidthTilePixels - 1) / m_hwWidthTilePixels; - m_hwHeightTiles = (m_hwHeightPixels + m_hwHeightTilePixels - 1) / m_hwHeightTilePixels; - m_hwWidthPixels = m_hwWidthTiles*m_hwWidthTilePixels; - m_hwHeightPixels = m_hwHeightTiles*m_hwHeightTilePixels; - - UINT sizeTileBytes = m_hwWidthTilePixels * m_hwHeightTilePixels * 4; - - m_hwSizeBytes = m_hwWidthTiles * m_hwHeightTiles * sizeTileBytes; - m_hwPitchBytes = 0; + CalculateTilesInfo(); } } break; @@ -449,24 +601,147 @@ bool RosUmdResource::CanRotateFrom(const RosUmdResource* Other) const (m_hwHeightTiles == Other->m_hwHeightTiles); } + +// Converts R, RG or A buffer to 32 bpp (RGBA) buffer +void RosUmdResource::ConvertBufferto32Bpp(const BYTE *pSrc, BYTE *pDst, UINT srcBpp, UINT swizzleMask, UINT pSrcStride, UINT pDstStride) +{ + for (UINT i = 0; i < m_mip0Info.TexelHeight; i++) + { + UINT32 *dstSwizzled = (UINT32*)pDst; + + UINT dstIndex = 0; + for (UINT k = 0; k < m_mip0Info.TexelWidth*srcBpp; k += srcBpp) + { + UINT32 swizzledRGBA = 0; + + // Gather individual color elements into one DWORD + for (UINT colorElement = 0; colorElement < srcBpp; colorElement++) + { + UINT32 currentColorElement = (UINT32)pSrc[k + colorElement]; + + // Move element to the right position + currentColorElement = currentColorElement << (colorElement << 3); + swizzledRGBA = swizzledRGBA | currentColorElement; + } + + swizzledRGBA = swizzledRGBA << swizzleMask; + dstSwizzled[dstIndex] = swizzledRGBA; + dstIndex += 1; + } + + pSrc += pSrcStride; + pDst += pDstStride; + } +} + +// Converts texture to internal (HW friendly) representation +void RosUmdResource::ConvertInitialTextureFormatToInternal(const BYTE *pSrc, BYTE *pDst, UINT rowStride) +{ + // HW supports only limited set of formats, so most of DXGI formats must + // be converted at the beginning. + UINT swizzleMask = 0; + UINT srcBpp = 0; + + switch (m_format) + { + case DXGI_FORMAT_R8G8B8A8_UNORM: + { + // Do nothing + } + break; + + case DXGI_FORMAT_R8_UNORM: + { + swizzleMask = 0; + srcBpp = 1; + } + break; + + case DXGI_FORMAT_R8G8_UNORM: + { + swizzleMask = 0; + srcBpp = 2; + } + break; + + case DXGI_FORMAT_A8_UNORM: + { + swizzleMask = 0; + srcBpp = 1; + } + break; + + default: + { + assert(false); + } + break; + } + + // For DXGI_FORMAT_R8G8B8A8_UNORM and DXGI_FORMAT_A8_UNORM we can do a simple copy or swizzle + // texture directly to memory. + if ((m_format == DXGI_FORMAT_R8G8B8A8_UNORM) || (m_format == DXGI_FORMAT_A8_UNORM)) + { + if (m_hwLayout == RosHwLayout::Linear) + { + for (UINT i = 0; i < m_mip0Info.TexelHeight; i++) + { + memcpy(pDst, pSrc, rowStride); + + pSrc += rowStride; + pDst += m_hwPitchBytes; + } + } + else + { + // Swizzle texture to HW format + ConvertBitmapTo4kTileBlocks(pSrc, pDst, rowStride); + } + } + else + { + // We have to convert other formats to internal format + if (m_hwLayout == RosHwLayout::Linear) + { + // Do a conversion directly to the locked allocation + ConvertBufferto32Bpp(pSrc, pDst, srcBpp, swizzleMask, rowStride, m_hwPitchBytes); + } + else + { + // For tiled layout, additional buffer is allocated. It is a + // conversion (temporary) buffer. + UINT pitch = m_mip0Info.TexelHeight * m_mip0Info.TexelWidth * 4; + + auto temporary = std::unique_ptr{ new BYTE[pitch] }; + + UINT dstStride = m_mip0Info.TexelWidth * 4; + + ConvertBufferto32Bpp(pSrc, temporary.get(), srcBpp, swizzleMask, rowStride, dstStride); + + ConvertBitmapTo4kTileBlocks(temporary.get(), pDst, dstStride); + + } + } +} + // Form 1k sub-tile block -BYTE *RosUmdResource::Form1kSubTileBlock(BYTE *pInputBuffer, BYTE *pOutBuffer, UINT rowStride) +BYTE *RosUmdResource::Form1kSubTileBlock(const BYTE *pInputBuffer, BYTE *pOutBuffer, UINT rowStride) { // 1k sub-tile block is formed from micro-tiles blocks - for (UINT h = 0; h < VC4_1KB_SUB_TILE_HEIGHT; h += 4) + for (UINT h = 0; h < m_TileInfo.VC4_1kBSubTileHeightPixels; h += m_TileInfo.vC4_MicroTileHeight) { - BYTE *currentBufferPos = pInputBuffer + h*rowStride; + const BYTE *currentBufferPos = pInputBuffer + h*rowStride; // Process row of 4 micro-tiles blocks - for (UINT w = 0; w < VC4_1KB_SUB_TILE_WIDTH_BYTES; w+= VC4_MICRO_TILE_WIDTH_BYTES) + for (UINT w = 0; w < m_TileInfo.VC4_1kBSubTileWidthBytes; w+= m_TileInfo.VC4_MicroTileWidthBytes) { - BYTE *microTileOffset = currentBufferPos + w; + const BYTE *microTileOffset = currentBufferPos + w; - // Process micro-tile block (4x16 bytes) - for (int t = 0; t < VC4_MICRO_TILE_HEIGHT; t++) + // Process micro-tile block + for (UINT t = 0; t < m_TileInfo.vC4_MicroTileHeight; t++) { - memcpy(pOutBuffer, microTileOffset, VC4_MICRO_TILE_WIDTH_BYTES); - pOutBuffer += VC4_MICRO_TILE_WIDTH_BYTES; + memcpy(pOutBuffer, microTileOffset, m_TileInfo.VC4_MicroTileWidthBytes); + pOutBuffer += m_TileInfo.VC4_MicroTileWidthBytes; microTileOffset += rowStride; } } @@ -475,9 +750,12 @@ BYTE *RosUmdResource::Form1kSubTileBlock(BYTE *pInputBuffer, BYTE *pOutBuffer, U } // Form one 4k tile block from pInputBuffer and store in pOutBuffer -BYTE *RosUmdResource::Form4kTileBlock(BYTE *pInputBuffer, BYTE *pOutBuffer, UINT rowStride, BOOLEAN OddRow) +BYTE *RosUmdResource::Form4kTileBlock(const BYTE *pInputBuffer, BYTE *pOutBuffer, UINT rowStride, BOOLEAN OddRow) { - BYTE *currentTileOffset = NULL; + const BYTE *currentTileOffset = NULL; + + UINT subTileHeightPixels = m_TileInfo.VC4_1kBSubTileHeightPixels; + UINT subTileWidthBytes = m_TileInfo.VC4_1kBSubTileWidthBytes; if (OddRow) { @@ -489,11 +767,11 @@ BYTE *RosUmdResource::Form4kTileBlock(BYTE *pInputBuffer, BYTE *pOutBuffer, UINT // // Get A block - currentTileOffset = pInputBuffer + rowStride * VC4_1KB_SUB_TILE_HEIGHT + VC4_1KB_SUB_TILE_WIDTH_BYTES; + currentTileOffset = pInputBuffer + rowStride * subTileHeightPixels + subTileWidthBytes; pOutBuffer = Form1kSubTileBlock(currentTileOffset, pOutBuffer, rowStride); // Get B block - currentTileOffset = pInputBuffer + VC4_1KB_SUB_TILE_WIDTH_BYTES; + currentTileOffset = pInputBuffer + subTileWidthBytes; pOutBuffer = Form1kSubTileBlock(currentTileOffset, pOutBuffer, rowStride); @@ -501,7 +779,7 @@ BYTE *RosUmdResource::Form4kTileBlock(BYTE *pInputBuffer, BYTE *pOutBuffer, UINT pOutBuffer = Form1kSubTileBlock(pInputBuffer, pOutBuffer, rowStride); // Get D block - currentTileOffset = pInputBuffer + rowStride * VC4_1KB_SUB_TILE_HEIGHT; + currentTileOffset = pInputBuffer + rowStride * subTileHeightPixels; pOutBuffer = Form1kSubTileBlock(currentTileOffset, pOutBuffer, rowStride); // return current position in out buffer @@ -521,15 +799,15 @@ BYTE *RosUmdResource::Form4kTileBlock(BYTE *pInputBuffer, BYTE *pOutBuffer, UINT pOutBuffer = Form1kSubTileBlock(pInputBuffer, pOutBuffer, rowStride); /// Get B block - currentTileOffset = pInputBuffer + rowStride * VC4_1KB_SUB_TILE_HEIGHT; + currentTileOffset = pInputBuffer + rowStride * subTileHeightPixels; pOutBuffer = Form1kSubTileBlock(currentTileOffset, pOutBuffer, rowStride); // Get C Block - currentTileOffset = pInputBuffer + rowStride * VC4_1KB_SUB_TILE_HEIGHT + VC4_1KB_SUB_TILE_WIDTH_BYTES; + currentTileOffset = pInputBuffer + rowStride * subTileHeightPixels + subTileWidthBytes; pOutBuffer = Form1kSubTileBlock(currentTileOffset, pOutBuffer, rowStride); // Get D block - currentTileOffset = pInputBuffer + VC4_1KB_SUB_TILE_WIDTH_BYTES; + currentTileOffset = pInputBuffer + subTileWidthBytes; pOutBuffer = Form1kSubTileBlock(currentTileOffset, pOutBuffer, rowStride); // return current position in out buffer @@ -538,10 +816,8 @@ BYTE *RosUmdResource::Form4kTileBlock(BYTE *pInputBuffer, BYTE *pOutBuffer, UINT } // Form (CountX * CountY) tile blocks from InputBuffer and store them in OutBuffer -void RosUmdResource::ConvertBitmapTo4kTileBlocks(BYTE *InputBuffer, BYTE *OutBuffer, UINT rowStride) +void RosUmdResource::ConvertBitmapTo4kTileBlocks(const BYTE *InputBuffer, BYTE *OutBuffer, UINT rowStride) { - // [todo] Currently only 32bpp mode is supported - UINT CountX = m_hwWidthTiles; UINT CountY = m_hwHeightTiles; @@ -553,7 +829,7 @@ void RosUmdResource::ConvertBitmapTo4kTileBlocks(BYTE *InputBuffer, BYTE *OutBuf // Build 4k blocks from right to left for odd rows for (int i = CountX - 1; i >= 0; i--) { - BYTE *blockStartOffset = InputBuffer + k * rowStride * VC4_4KB_TILE_HEIGHT + i * VC4_4KB_TILE_WIDTH_BYTES; + const BYTE *blockStartOffset = InputBuffer + k * rowStride * m_TileInfo.VC4_4kBTileHeightPixels + i * m_TileInfo.VC4_4kBTileWidthBytes; OutBuffer = Form4kTileBlock(blockStartOffset, OutBuffer, rowStride, oddRow); } } @@ -562,7 +838,7 @@ void RosUmdResource::ConvertBitmapTo4kTileBlocks(BYTE *InputBuffer, BYTE *OutBuf // Build 4k blocks from left to right for even rows for (UINT i = 0; i < CountX; i++) { - BYTE *blockStartOffset = InputBuffer + k * rowStride * VC4_4KB_TILE_HEIGHT + i * VC4_4KB_TILE_WIDTH_BYTES; + const BYTE *blockStartOffset = InputBuffer + k * rowStride * m_TileInfo.VC4_4kBTileHeightPixels + i * m_TileInfo.VC4_4kBTileWidthBytes; OutBuffer = Form4kTileBlock(blockStartOffset, OutBuffer, rowStride, oddRow); } } diff --git a/render-only-sample/rosumd/RosUmdResource.h b/render-only-sample/rosumd/RosUmdResource.h index e9a5231..309967d 100644 --- a/render-only-sample/rosumd/RosUmdResource.h +++ b/render-only-sample/rosumd/RosUmdResource.h @@ -3,6 +3,7 @@ #include "RosAllocation.h" #include "Pixel.hpp" #include "RosUmdDebug.h" +#include "Vc4Hw.h" class RosUmdResource : public RosAllocationExchange { @@ -39,6 +40,9 @@ class RosUmdResource : public RosAllocationExchange // Used by constant buffer BYTE *m_pSysMemCopy; + // Tiled textures information + VC4TileInfo m_TileInfo; + void Standup( RosUmdDevice *pUmdDevice, @@ -101,26 +105,59 @@ class RosUmdResource : public RosAllocationExchange return m_isPrimary; } - // Tiled textures support - void ConvertBitmapTo4kTileBlocks( - BYTE *InputBuffer, - BYTE *OutBuffer, + bool IsMapped() + { + return nullptr != m_pData; + } + + bool IsMultisampled() + { + return m_sampleDesc.Count > 1; + } + + // Support for various texture formats + void ConvertInitialTextureFormatToInternal( + const BYTE *pSrc, + BYTE *pDst, UINT rowStride); private: + void ConvertBufferto32Bpp( + const BYTE *pSrc, + BYTE *pDst, + UINT srcBpp, + UINT swizzleMask, + UINT pSrcStride, + UINT pDstStride); + + // Tiled textures support + void ConvertBitmapTo4kTileBlocks( + const BYTE *InputBuffer, + BYTE *OutBuffer, + UINT rowStride); + // Tiled textures support BYTE *Form1kSubTileBlock( - BYTE *pInputBuffer, + const BYTE *pInputBuffer, BYTE *pOutBuffer, UINT rowStride); BYTE *Form4kTileBlock( - BYTE *pInputBuffer, + const BYTE *pInputBuffer, BYTE *pOutBuffer, UINT rowStride, BOOLEAN OddRow); + static void MapDxgiFormatToInternalFormats( + DXGI_FORMAT format, + _Out_ UINT &bpp, + _Out_ RosHwFormat &rosFormat); + + void CalculateTilesInfo(); + + static VC4TileInfo FillTileInfo(UINT bpp); + }; inline RosUmdResource* RosUmdResource::CastFrom(D3D10DDI_HRESOURCE hResource) diff --git a/render-only-sample/rosumd/RosUmdSampler.h b/render-only-sample/rosumd/RosUmdSampler.h index 5792ab8..e75be69 100644 --- a/render-only-sample/rosumd/RosUmdSampler.h +++ b/render-only-sample/rosumd/RosUmdSampler.h @@ -2,8 +2,6 @@ #pragma once -#include "d3dumddi_.h" - class RosUmdSampler { friend class RosUmdDevice; diff --git a/render-only-sample/rosumd/RosUmdShader.cpp b/render-only-sample/rosumd/RosUmdShader.cpp index 3d745c8..cfe4045 100644 --- a/render-only-sample/rosumd/RosUmdShader.cpp +++ b/render-only-sample/rosumd/RosUmdShader.cpp @@ -5,6 +5,11 @@ // Copyright (C) Microsoft Corporation // //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#include "precomp.h" + +#include "RosUmdLogging.h" +#include "RosUmdShader.tmh" + #include "RosUmdDevice.h" #include "RosUmdShader.h" diff --git a/render-only-sample/rosumd/RosUmdShader.h b/render-only-sample/rosumd/RosUmdShader.h index f03e303..e0f1248 100644 --- a/render-only-sample/rosumd/RosUmdShader.h +++ b/render-only-sample/rosumd/RosUmdShader.h @@ -1,8 +1,7 @@ #pragma once -#include "d3dumddi_.h" #include "RosUmdDevice.h" -#include "..\roscompiler\roscompiler.h" +#include class RosUmdShader { diff --git a/render-only-sample/rosumd/RosUmdShaderResourceView.h b/render-only-sample/rosumd/RosUmdShaderResourceView.h index 58a5e31..7ea8d3d 100644 --- a/render-only-sample/rosumd/RosUmdShaderResourceView.h +++ b/render-only-sample/rosumd/RosUmdShaderResourceView.h @@ -1,7 +1,5 @@ #pragma once -#include "d3dumddi_.h" - class RosUmdShaderResourceView { friend class RosUmdDevice; diff --git a/render-only-sample/rosumd/RosUmdUtil.cpp b/render-only-sample/rosumd/RosUmdUtil.cpp index d44c885..0e4fc40 100644 --- a/render-only-sample/rosumd/RosUmdUtil.cpp +++ b/render-only-sample/rosumd/RosUmdUtil.cpp @@ -6,9 +6,12 @@ // //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -#include "d3dumddi_.h" +#include "precomp.h" + +#include "RosUmdLogging.h" +#include "RosUmdUtil.tmh" + #include "RosUmdUtil.h" -#include #if VC4 diff --git a/render-only-sample/rosumd/RosUmdUtil.h b/render-only-sample/rosumd/RosUmdUtil.h index f7f80e0..29a00bd 100644 --- a/render-only-sample/rosumd/RosUmdUtil.h +++ b/render-only-sample/rosumd/RosUmdUtil.h @@ -54,7 +54,7 @@ ConvertD3D11TextureMinFilter( #endif -inline operator== (const D3D10DDI_MIPINFO &Lhs, const D3D10DDI_MIPINFO &Rhs) +inline bool operator== (const D3D10DDI_MIPINFO &Lhs, const D3D10DDI_MIPINFO &Rhs) { return (Lhs.TexelWidth == Rhs.TexelWidth) && (Lhs.TexelHeight == Rhs.TexelHeight) && @@ -64,18 +64,18 @@ inline operator== (const D3D10DDI_MIPINFO &Lhs, const D3D10DDI_MIPINFO &Rhs) (Lhs.PhysicalDepth == Rhs.PhysicalDepth); } -inline operator== (const DXGI_SAMPLE_DESC &Lhs, const DXGI_SAMPLE_DESC &Rhs) +inline bool operator== (const DXGI_SAMPLE_DESC &Lhs, const DXGI_SAMPLE_DESC &Rhs) { return (Lhs.Count == Rhs.Count) && (Lhs.Quality == Rhs.Quality); } -inline operator== (const DXGI_DDI_RATIONAL &Lhs, const DXGI_DDI_RATIONAL &Rhs) +inline bool operator== (const DXGI_DDI_RATIONAL &Lhs, const DXGI_DDI_RATIONAL &Rhs) { return (Lhs.Numerator == Rhs.Numerator) && (Lhs.Denominator == Rhs.Denominator); } -inline operator== (const DXGI_DDI_MODE_DESC &Lhs, const DXGI_DDI_MODE_DESC &Rhs) +inline bool operator== (const DXGI_DDI_MODE_DESC &Lhs, const DXGI_DDI_MODE_DESC &Rhs) { return (Lhs.Width == Rhs.Width) && (Lhs.Height == Rhs.Height) && @@ -86,7 +86,7 @@ inline operator== (const DXGI_DDI_MODE_DESC &Lhs, const DXGI_DDI_MODE_DESC &Rhs) (Lhs.Scaling == Rhs.Scaling); } -inline operator== (const DXGI_DDI_PRIMARY_DESC &Lhs, const DXGI_DDI_PRIMARY_DESC &Rhs) +inline bool operator== (const DXGI_DDI_PRIMARY_DESC &Lhs, const DXGI_DDI_PRIMARY_DESC &Rhs) { return (Lhs.Flags == Rhs.Flags) && (Lhs.VidPnSourceId == Rhs.VidPnSourceId) && diff --git a/render-only-sample/rosumd/pixel.cpp b/render-only-sample/rosumd/pixel.cpp index b8f7b24..cd7df7e 100644 --- a/render-only-sample/rosumd/pixel.cpp +++ b/render-only-sample/rosumd/pixel.cpp @@ -8,7 +8,7 @@ * ***************************************************************************/ -#include "strsafe.h" +#include "precomp.h" #include "pixel.hpp" #ifndef DXPIXELVER diff --git a/render-only-sample/rosumd/pixel.hpp b/render-only-sample/rosumd/pixel.hpp index 3e04309..2c274f6 100644 --- a/render-only-sample/rosumd/pixel.hpp +++ b/render-only-sample/rosumd/pixel.hpp @@ -21,8 +21,6 @@ #define DXGASSERT( x ) _Analysis_assume_( x ); #endif -#include - struct IHVFormatInfo { DXGI_FORMAT m_Format; diff --git a/render-only-sample/rosumd/pixlib.cpp b/render-only-sample/rosumd/pixlib.cpp index 89dc71f..c523788 100644 --- a/render-only-sample/rosumd/pixlib.cpp +++ b/render-only-sample/rosumd/pixlib.cpp @@ -1,4 +1,8 @@ +#include "precomp.h" + +#include "RosUmdLogging.h" +#include "pixlib.tmh" #include "pixel.cpp" diff --git a/render-only-sample/rosumd/precomp.cpp b/render-only-sample/rosumd/precomp.cpp new file mode 100644 index 0000000..ceeb0d6 --- /dev/null +++ b/render-only-sample/rosumd/precomp.cpp @@ -0,0 +1 @@ +#include "precomp.h" diff --git a/render-only-sample/rosumd/precomp.h b/render-only-sample/rosumd/precomp.h new file mode 100644 index 0000000..4f8015a --- /dev/null +++ b/render-only-sample/rosumd/precomp.h @@ -0,0 +1,18 @@ +#ifndef _ROSUMD_PRECOMP_H_ +#define _ROSUMD_PRECOMP_H_ + +#include +#include +#include +#include "d3dumddi_.h" +#include + +#include +#include +#include + +#include +#include +#include + +#endif // _ROSUMD_PRECOMP_H_ diff --git a/render-only-sample/rosumd/rosumd.vcxproj b/render-only-sample/rosumd/rosumd.vcxproj index 13e8754..e7cb6af 100644 --- a/render-only-sample/rosumd/rosumd.vcxproj +++ b/render-only-sample/rosumd/rosumd.vcxproj @@ -34,135 +34,32 @@ ARM64 - - - - - - - - false - false - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {B87732A7-0D66-4692-96E2-2772BF77C3FC} {9181db3b-298d-4e39-a572-55bca4e4ac89} - v4.5.2 - 12.0 - Debug - Win32 + Debug + ARM rosumd $(LatestTargetPlatformVersion) false - + Windows10 - true WindowsUserModeDriver10.0 DynamicLibrary 2 Universal Unicode - - Windows10 - false - WindowsUserModeDriver10.0 - DynamicLibrary - 2 - Universal - Unicode - - - Windows10 + + true - WindowsUserModeDriver10.0 - DynamicLibrary - 2 - Universal - Unicode - - - Windows10 - false - WindowsUserModeDriver10.0 - DynamicLibrary - 2 - Universal - Unicode - - - Windows10 - true - WindowsUserModeDriver10.0 - DynamicLibrary - 2 - Universal - Unicode - - - Windows10 - false - WindowsUserModeDriver10.0 - DynamicLibrary - 2 - Universal - Unicode - - - Windows10 - true - WindowsUserModeDriver10.0 - DynamicLibrary - 2 - Universal - Unicode - - Windows10 + + false - WindowsUserModeDriver10.0 - DynamicLibrary - 2 - Universal - Unicode @@ -171,204 +68,112 @@ - - - DbgengRemoteDebugger - $(IncludePath);$(KM_IncludePath);$(SolutionDir)\roscommon + false false - $(SDK_LibraryPath_DDKPlatform);$(LibraryPath) - - DbgengRemoteDebugger - $(IncludePath);$(KM_IncludePath);$(SolutionDir)\roscommon - false - false - - - DbgengRemoteDebugger - $(IncludePath);$(KM_IncludePath);$(SolutionDir)\roscommon - false - false - $(SDK_LibraryPath_DDKPlatform);$(LibraryPath) - - - DbgengRemoteDebugger - $(IncludePath);$(KM_IncludePath);$(SolutionDir)\roscommon - false - false - - - DbgengRemoteDebugger - $(IncludePath);$(KM_IncludePath);$(SolutionDir)\roscommon - false - $(SDK_LibraryPath_DDKPlatform);$(LibraryPath) - - - DbgengRemoteDebugger - $(IncludePath);$(KM_IncludePath);$(SolutionDir)\roscommon - false - - - DbgengRemoteDebugger - $(IncludePath);$(KM_IncludePath);$(SolutionDir)\roscommon - false - false - $(SDK_LibraryPath_DDKPlatform);$(LibraryPath) - - - DbgengRemoteDebugger - $(IncludePath);$(KM_IncludePath);$(SolutionDir)\roscommon - false - false - - - - false - true - trace.h - Sync - true - 4201;%(DisableSpecificWarnings) - VC4=1;_X86_=1;i386=1;STD_CALL;%(PreprocessorDefinitions) - - - RosUmd.def - %(AdditionalDependencies);roscompiler.lib - $(OutDir) - false - - - false - - - - - false - true - trace.h - Sync - true - VC4=1;_X86_=1;i386=1;STD_CALL;%(PreprocessorDefinitions) - - - RosUmd.def - %(AdditionalDependencies);roscompiler.lib - $(OutDir) - false - - - - - false - true - trace.h - Sync - true - 4201;%(DisableSpecificWarnings) - VC4=1;_WIN64;_AMD64_;AMD64;%(PreprocessorDefinitions) - - - RosUmd.def - %(AdditionalDependencies);roscompiler.lib - $(OutDir) - false - - - false - - - + + - false - true - trace.h + Use + precomp.h + Level4 + true + + true Sync - true - VC4=1;_WIN64;_AMD64_;AMD64;%(PreprocessorDefinitions) + 4201; + VC4=1;_USE_DECLSPECS_FOR_SAL=1;%(PreprocessorDefinitions) + ..\roscompiler;..\roscommon;$(KM_IncludePath);%(AdditionalIncludeDirectories) + true + true + ..\roscommon\RosLogging.h + false + ROSUMD + WPP_EMIT_FUNC_NAME RosUmd.def - %(AdditionalDependencies);roscompiler.lib + roscompiler.lib;onecoreuap.lib $(OutDir) - false - - - - - false - true - trace.h - Sync - true - 4201;%(DisableSpecificWarnings) - VC4=1;_ARM_;ARM;_USE_DECLSPECS_FOR_SAL=1;STD_CALL;%(PreprocessorDefinitions) - - - RosUmd.def - %(AdditionalDependencies);roscompiler.lib - $(OutDir) - false + true false - - - false - true - trace.h - Sync - true - VC4=1;_ARM_;ARM;_USE_DECLSPECS_FOR_SAL=1;STD_CALL;%(PreprocessorDefinitions) - - - RosUmd.def - %(AdditionalDependencies);roscompiler.lib - $(OutDir) - false - - - + + - false - true - trace.h - Sync + false true - 4201;%(DisableSpecificWarnings) - VC4=1;_ARM64_;ARM64;_USE_DECLSPECS_FOR_SAL=1;STD_CALL;%(PreprocessorDefinitions) - RosUmd.def - %(AdditionalDependencies);roscompiler.lib - $(OutDir) - false + msvcrtd.lib;vcruntimed.lib;ucrtd.lib;%(AdditionalDependencies) + Default - - false - - + + - false - true - trace.h - Sync + true true - VC4=1;_ARM64_;ARM64;_USE_DECLSPECS_FOR_SAL=1;STD_CALL;%(PreprocessorDefinitions) - RosUmd.def - %(AdditionalDependencies);roscompiler.lib - $(OutDir) - false + msvcrt.lib;vcruntime.lib;ucrt.lib;%(AdditionalDependencies) + UseLinkTimeCodeGeneration + + + + + + Create + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/render-only-sample/rosumd/rosumd.vcxproj.filters b/render-only-sample/rosumd/rosumd.vcxproj.filters index f299a6f..65cb9ca 100644 --- a/render-only-sample/rosumd/rosumd.vcxproj.filters +++ b/render-only-sample/rosumd/rosumd.vcxproj.filters @@ -134,5 +134,8 @@ Source Files + + Source Files + \ No newline at end of file diff --git a/render-only-sample/scripts/Firmware.zip b/render-only-sample/scripts/Firmware.zip index 5bf3099..6e5264b 100644 Binary files a/render-only-sample/scripts/Firmware.zip and b/render-only-sample/scripts/Firmware.zip differ diff --git a/render-only-sample/scripts/IotShell.exe b/render-only-sample/scripts/IotShell.exe new file mode 100644 index 0000000..89a1da5 Binary files /dev/null and b/render-only-sample/scripts/IotShell.exe differ diff --git a/vc4_test/Makefile b/vc4_test/Makefile deleted file mode 100644 index f1e063b..0000000 --- a/vc4_test/Makefile +++ /dev/null @@ -1,7 +0,0 @@ - -test: test.cpp mailbox.o v3d.h - g++ -o test -Wall -Wextra test.cpp mailbox.o -g - -mailbox.o: mailbox.c mailbox.h - g++ -c -o mailbox.o -Wall -Wextra mailbox.c -g - diff --git a/vc4_test/mailbox.c b/vc4_test/mailbox.c deleted file mode 100644 index 9e9528b..0000000 --- a/vc4_test/mailbox.c +++ /dev/null @@ -1,258 +0,0 @@ -/* -Copyright (c) 2012, Broadcom Europe Ltd. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * Neither the name of the copyright holder nor the - names of its contributors may be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "mailbox.h" - -#define PAGE_SIZE (4*1024) - -void *mapmem(unsigned int base, unsigned int size) -{ - int mem_fd; - unsigned offset = base % PAGE_SIZE; - base = base - offset; - /* open /dev/mem */ - if ((mem_fd = open("/dev/mem", O_RDWR|O_SYNC) ) < 0) { - printf("can't open /dev/mem\nThis program should be run as root. Try prefixing command with: sudo\n"); - exit (-1); - } - void *mem = mmap( - 0, - size, - PROT_READ|PROT_WRITE, - MAP_SHARED/*|MAP_FIXED*/, - mem_fd, - base); -#ifdef DEBUG - printf("base=0x%x, mem=%p\n", base, mem); -#endif - if (mem == MAP_FAILED) { - printf("mmap error %d\n", (int)mem); - exit (-1); - } - close(mem_fd); - return (char *)mem + offset; -} - -void *unmapmem(void *addr, unsigned int size) -{ - int s = munmap(addr, size); - if (s != 0) { - printf("munmap error %d\n", s); - exit (-1); - } -} - -/* - * use ioctl to send mbox property message - */ - -static int mbox_property(int file_desc, void *buf) -{ - int ret_val = ioctl(file_desc, IOCTL_MBOX_PROPERTY, buf); - - if (ret_val < 0) { - printf("ioctl_set_msg failed:%d\n", ret_val); - } - -#ifdef DEBUG - unsigned int *p = buf; int i; unsigned int size = *(unsigned int *)buf; - for (i=0; i - -#define MAJOR_NUM 100 -#define IOCTL_MBOX_PROPERTY _IOWR(MAJOR_NUM, 0, char *) -#define DEVICE_FILE_NAME "/dev/vcio" - -int mbox_open(); -void mbox_close(int file_desc); - -unsigned int get_version(int file_desc); -unsigned int mem_alloc(int file_desc, unsigned int size, unsigned int align, unsigned int flags); -unsigned int mem_free(int file_desc, unsigned int handle); -unsigned int mem_lock(int file_desc, unsigned int handle); -unsigned int mem_unlock(int file_desc, unsigned int handle); -void *mapmem(unsigned int base, unsigned int size); -void *unmapmem(void *addr, unsigned int size); - -unsigned int execute_code(int file_desc, unsigned int code, unsigned int r0, unsigned int r1, unsigned int r2, unsigned int r3, unsigned int r4, unsigned int r5); -unsigned int execute_qpu(int file_desc, unsigned int num_qpus, unsigned int control, unsigned int noflush, unsigned int timeout); -unsigned int qpu_enable(int file_desc, unsigned int enable); - - -// Flags for allocate memory. -enum { -MEM_FLAG_DISCARDABLE = 1 << 0, /* can be resized to 0 at any time. Use for cached data */ -MEM_FLAG_NORMAL = 0 << 2, /* normal allocating alias. Don't use from ARM */ -MEM_FLAG_DIRECT = 1 << 2, /* 0xC alias uncached */ -MEM_FLAG_COHERENT = 2 << 2, /* 0x8 alias. Non-allocating in L2 but coherent */ -MEM_FLAG_L1_NONALLOCATING = (MEM_FLAG_DIRECT | MEM_FLAG_COHERENT), /* Allocating in L2 */ -MEM_FLAG_ZERO = 1 << 4, /* initialise buffer to all zeros */ -MEM_FLAG_NO_INIT = 1 << 5, /* don't initialise (default is initialise to all ones */ -MEM_FLAG_HINT_PERMALOCK = 1 << 6, /* Likely to be locked for long periods of time. */ -}; - -#ifdef C_PLUS_PLUS -} -#endif diff --git a/vc4_test/test.cpp b/vc4_test/test.cpp deleted file mode 100644 index 32ef980..0000000 --- a/vc4_test/test.cpp +++ /dev/null @@ -1,710 +0,0 @@ -/* -The MIT License (MIT) - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "mailbox.h" -#include "v3d.h" - -// I/O access -volatile unsigned *v3d; -int mbox; - -#define USE_TEX 1 - -#define screen_x 1024 -#define screen_y 1024 - -int tile_x = (screen_x / 64) + ((screen_x % 64) ? 1 : 0); -int tile_y = (screen_y / 64) + ((screen_y % 64) ? 1 : 0); - -#define tex_x 16 -#define tex_y 16 - -int SaveBMP(const char* pFileName, void *pImage) -{ - FILE * fp = NULL; - - fp = fopen(pFileName, "wb"); - -#pragma pack(push, 2) - - struct BMPHeader - { - uint16_t m_id; - uint32_t m_fileSize; - uint32_t m_unused; - uint32_t m_pixelArrayOffset; - }; - - struct DIBHeader - { - uint32_t m_dibHeaderSize; - uint32_t m_widthPixels; - uint32_t m_heightPixels; - uint16_t m_numPlanes; - uint16_t m_bitsPerPixel; - uint32_t m_compressionMethod; - uint32_t m_pixelDataSize; - uint32_t m_pixelsPerMeterHorizontal; - uint32_t m_pixelsPerMeterVertical; - uint32_t m_colorsInPalette; - uint32_t m_importantColors; - }; - -#pragma pack(pop) - - uint32_t pixelWidth = screen_x; - uint32_t pixelHeight = screen_y; - uint32_t byteWidthNoPadding = pixelWidth * 3; - uint32_t byteWidth = (byteWidthNoPadding + 3) & ~3; - uint32_t bytePadding = byteWidth - byteWidthNoPadding; - uint32_t pixelDataSize = byteWidth * pixelHeight; - - BMPHeader bmpHeader; - - bmpHeader.m_id = 0x4D42; - bmpHeader.m_fileSize = sizeof(BMPHeader) + sizeof(DIBHeader) + pixelDataSize; - bmpHeader.m_pixelArrayOffset = sizeof(BMPHeader) + sizeof(DIBHeader); - bmpHeader.m_unused = 0; - - DIBHeader dibHeader; - - dibHeader.m_bitsPerPixel = 24; - dibHeader.m_colorsInPalette = 0; - dibHeader.m_compressionMethod = 0; - dibHeader.m_dibHeaderSize = sizeof(DIBHeader); - dibHeader.m_heightPixels = pixelHeight; - dibHeader.m_importantColors = 0; - dibHeader.m_numPlanes = 1; - dibHeader.m_pixelDataSize = pixelDataSize; - dibHeader.m_pixelsPerMeterHorizontal = 2835; - dibHeader.m_pixelsPerMeterVertical = 2835; - dibHeader.m_widthPixels = pixelWidth; - - fwrite(&bmpHeader, sizeof(bmpHeader), 1, fp); - fwrite(&dibHeader, sizeof(dibHeader), 1, fp); - - uint8_t * pData = reinterpret_cast(pImage); - assert(pData); - - int padding = 0; - for (uint32_t row = 0; row < pixelHeight; row++) - { - uint8_t * pRow = pData + ((pixelHeight - row - 1) * (pixelWidth * 4)); - - for (uint32_t col = 0; col < pixelWidth; col++) - { - fwrite(pRow + 0, 1, 1, fp); - fwrite(pRow + 1, 1, 1, fp); - fwrite(pRow + 2, 1, 1, fp); - - pRow += 4; - } - if (bytePadding) fwrite(&padding, 1, bytePadding, fp); - } - - fclose(fp); - - return 0; -} - -void addbyte(uint8_t **list, uint8_t d) { - *((*list)++) = d; -} - -void addshort(uint8_t **list, uint16_t d) { - *((*list)++) = (d) & 0xff; - *((*list)++) = (d >> 8) & 0xff; -} - -void addword(uint8_t **list, uint32_t d) { - *((*list)++) = (d) & 0xff; - *((*list)++) = (d >> 8) & 0xff; - *((*list)++) = (d >> 16) & 0xff; - *((*list)++) = (d >> 24) & 0xff; -} - -void addfloat(uint8_t **list, float f) { - uint32_t d = *((uint32_t *)&f); - *((*list)++) = (d) & 0xff; - *((*list)++) = (d >> 8) & 0xff; - *((*list)++) = (d >> 16) & 0xff; - *((*list)++) = (d >> 24) & 0xff; -} - -// Memory Map - -enum bo { - BO_BCL, - BO_INDEX, - BO_TSD, - BO_TA, - BO_RCL, - BO_FS, - BO_VSUNIFORM, - BO_CSUNIFORM, - BO_VS, - BO_CS, - BO_VERTEX, - BO_SHADER, - BO_FSUNIFORM, - BO_TEXTURE, - BO_FB, - BO_TOTAL, -}; - -uint32_t offsets[] = { - 0, // binning control list - 0x80, // index buffer - 0x100, // tile state data address - 0x6200, // tile allocation memory address. 32bytes per tile. - 0xe200, // render control list - 0xfe00, // FS shader - 0x10000, // VS uniforms - 0x10080, // CS uniforms - 0x10100, // VS shader - 0x10200, // CS shader - 0x10300, // vertex buffer - 0x10800, // shader record; - 0x10a00, // FS uniforms - 0x11000, // texture data; must be 1k aligned; - 0x20000, // frame buffer - 0xa00000, // Total size -}; - -// Render a single triangle to memory. -void testTriangle() { - // Like above, we allocate/lock/map some videocore memory - // I'm just shoving everything in a single buffer because I'm lazy - // 8Mb, 4k alignment - unsigned int handle = mem_alloc(mbox, offsets[BO_TOTAL], 0x1000, MEM_FLAG_DIRECT | MEM_FLAG_ZERO); - if (!handle) { - printf("Error: Unable to allocate memory"); - return; - } - uint32_t bus_addr = mem_lock(mbox, handle); - uint8_t *list = (uint8_t*) mapmem((bus_addr & ~0xC0000000), offsets[BO_TOTAL]); - - printf("TA size check: %d %d\n", (tile_x * 32 * tile_y), (offsets[BO_TA+1] - offsets[BO_TA])); // make sure tile allocation memory is enough - assert((tile_x * 32 * tile_y) < (offsets[BO_TA+1] - offsets[BO_TA])); // make sure tile allocation memory is enough - - printf("FB size check: %d %d\n", (screen_x * 4 * screen_y), (offsets[BO_FB+1] - offsets[BO_FB])); // make file frame buffer is enough - assert((screen_x * 4 * screen_y) < (offsets[BO_FB+1] - offsets[BO_FB])); // make sure frame buffer is enough - - printf("TEXTURE size check: %d %d\n", (tex_x * 4 * tex_y), (offsets[BO_TEXTURE+1] - offsets[BO_TEXTURE])); // make file frame buffer is enough - assert((tex_x * 4 * tex_y) < (offsets[BO_TEXTURE+1] - offsets[BO_TEXTURE])); // make sure texture buffer is enough - - assert((offsets[BO_SHADER] & 0x7) == 0); - assert((offsets[BO_TEXTURE] & 0xfff) == 0); - - uint8_t *p = list; - - // Configuration stuff - // Tile Binning Configuration. - // Tile state data is 48 bytes per tile, I think it can be thrown away - // as soon as binning is finished. - addbyte(&p, 112); - addword(&p, bus_addr + offsets[BO_TA]); // tile allocation memory address - addword(&p, offsets[BO_TA + 1] - offsets[BO_TA]); // tile allocation memory size - addword(&p, bus_addr + offsets[BO_TSD]); // Tile state data address - addbyte(&p, tile_x); // number of tile - addbyte(&p, tile_y); // number of tile - addbyte(&p, 0x04); // config - - // Start tile binning. - addbyte(&p, 6); - - // Primitive type - addbyte(&p, 56); - addbyte(&p, 0x12); // 16 bit index, triangle - - // Raster State - addbyte(&p, 96); - addbyte(&p, 0x07); // enable both foward and back facing polygons - addbyte(&p, 0x00); // depth testing disabled - addbyte(&p, 0x02); // enable early depth write - - // Clip Window - addbyte(&p, 102); - addshort(&p, 0); - addshort(&p, 0); - addshort(&p, screen_x); // width - addshort(&p, screen_y); // height - - // Viewport offset - addbyte(&p, 103); - addshort(&p, (int16_t)((screen_x / 2) * 16.0f)); // width - addshort(&p, (int16_t)((screen_y / 2) * 16.0f)); // height - - // Z min/max - //addbyte(&p, 104); - //addfloat(&p, 0.0f); // min - //addfloat(&p, 1.0f); // max - - // clipper x/y scaling - addbyte(&p, 105); - addfloat(&p, (screen_x / 2) * 16.0f); // width - addfloat(&p, (screen_y / 2) * 16.0f); // hight - - // clipper z scaling - addbyte(&p, 106); - addfloat(&p, 1.0f); // scale - addfloat(&p, 0.0f); // offset - - // GL shader state - addbyte(&p, 64); - addword(&p, (bus_addr + offsets[BO_SHADER]) | 0x1); // Shader Record | number of attributes - - // primitive index list - addbyte(&p, 32); - addbyte(&p, 0x04); // 8bit index, trinagles - addword(&p, 3); // Length - addword(&p, bus_addr + offsets[BO_INDEX]); // index buffer address - addword(&p, 2); // Maximum index - - // End of bin list - // Flush - addbyte(&p, 5); - // Nop - addbyte(&p, 1); - // Halt - addbyte(&p, 0); - - int length = p - list; - assert(length < (offsets[BO_RCL + 1] - offsets[BO_RCL])); - -// index buffer - p = list + offsets[BO_INDEX]; - addbyte(&p, 0); // top - addbyte(&p, 1); // bottom left - addbyte(&p, 2); // bottom right - -// Vertex Data - p = list + offsets[BO_VERTEX]; -#if USE_TEX - #define NUM_VERTEX 6 - #define NUM_VARY 2 -#else - #define NUM_VERTEX 7 - #define NUM_VARY 3 -#endif // USE_TEX - - addfloat(&p, 0.0f); // Xc - addfloat(&p, -0.5f); // Yc - addfloat(&p, 1.0f); // Z - addfloat(&p, 1.0f); // W -#if USE_TEX - addfloat(&p, 0.0f); // t - addfloat(&p, 0.5f); // s -#else - addfloat(&p, 1.0f); // Varying 0 (b) - addfloat(&p, 0.0f); // Varying 1 (g) - addfloat(&p, 0.0f); // Varying 2 (r) -#endif // USE_TEX - - addfloat(&p, -1.0f); // Xc - addfloat(&p, 1.0f); // Yc - addfloat(&p, 1.0f); // Z - addfloat(&p, 1.0f); // W -#if USE_TEX - addfloat(&p, 1.0f); // t - addfloat(&p, 0.0f); // s -#else - addfloat(&p, 0.0f); // Varying 0 (b) - addfloat(&p, 1.0f); // Varying 1 (g) - addfloat(&p, 0.0f); // Varying 2 (r) -#endif // USE_TEX - - addfloat(&p, 1.0f); // Xc - addfloat(&p, 1.0f); // Yc - addfloat(&p, 1.0f); // Z - addfloat(&p, 1.0f); // W -#if USE_TEX - addfloat(&p, 1.0f); // t - addfloat(&p, 1.0f); // s -#else - addfloat(&p, 0.0f); // Varying 0 (b) - addfloat(&p, 0.0f); // Varying 1 (g) - addfloat(&p, 1.0f); // Varying 2 (r) -#endif // USE_TEX - -// VS uniforms - p = list + offsets[BO_VSUNIFORM]; -#define NUM_VSUNIFORM 2 - addfloat(&p, ((screen_x / 2) * 16.0f)); - addfloat(&p, ((screen_y / 2) * 16.0f)); - -// CS uniforms -#define NUM_CSUNIFORM 2 - p = list + offsets[BO_CSUNIFORM]; - addfloat(&p, ((screen_x / 2) * 16.0f)); - addfloat(&p, ((screen_y / 2) * 16.0f)); - -// FS uniforms - p = list + offsets[BO_FSUNIFORM]; -#if USE_TEX - #define NUM_FSUNIFORM 2 - addword(&p, ((1 << 4) | // texture data type RGBX8888 - ((bus_addr + offsets[BO_TEXTURE])))); - addword(&p, ((1 << 4) | // Nearest - (1 << 7) | // Neaaest - (tex_x << 8) | - (tex_y << 20))); -#else - #define NUM_FSUNIFORM 0 -#endif // USE_TEX - -// Texture data - p = list + offsets[BO_TEXTURE]; - uint32_t *pTex = (uint32_t*)p; - for (uint32_t x = 0; x < tex_x * 4 * tex_y; x++) { - if (x & (1 << 4)) { - *pTex = (x & (1 << 6)) ? 0xff0000ff : 0xff00ff00; - } else { - *pTex = (x & (1 << 6)) ? 0xff00ff00 : 0xff0000ff; - } - pTex++; - } - -// GL Shader Record - p = list + offsets[BO_SHADER]; - addshort(&p, 0x05); // enable clipping - - addbyte(&p, NUM_FSUNIFORM); // FS: number of uniforms - addbyte(&p, NUM_VARY); // FS: number of varying - addword(&p, bus_addr + offsets[BO_FS]); // FS code - addword(&p, bus_addr + offsets[BO_FSUNIFORM]); // FS uniforms - - addshort(&p, NUM_VSUNIFORM); // VS: number of uniforms - addbyte(&p, 1); // VS: number of attributes - addbyte(&p, NUM_VERTEX*4); // VS: total attribute size - addword(&p, bus_addr + offsets[BO_VS]); // VS shader code - addword(&p, bus_addr + offsets[BO_VSUNIFORM]); // VS uniforms - - addshort(&p, NUM_CSUNIFORM); // CS: number of uniforms - addbyte(&p, 1); // CS: number of attributes - addbyte(&p, NUM_VERTEX*4); // CS: total attribute size - addword(&p, bus_addr + offsets[BO_CS]); // CS shader code - addword(&p, bus_addr + offsets[BO_CSUNIFORM]); // CS uniforms - - addword(&p, bus_addr + offsets[BO_VERTEX]); // Vertex Data - addbyte(&p, (NUM_VERTEX*4)-1); // bytes - 1 in attributes - addbyte(&p, NUM_VERTEX*4); // stride - addbyte(&p, 0); // VS: VPM offset - addbyte(&p, 0); // CS: VPM offset - -// fragment shader - p = list + offsets[BO_FS]; - uint64_t fs[] = { -#if USE_TEX - 0x10020827158e7d80, // ; mov r0, varying ; nop // pm = 0, sf = 0, ws = 0 - 0x10020867158e7d80, // ; mov r1, varying ; nop // pm = 0, sf = 0, ws = 0 - 0x400208a7019e7140, // sbwait ; fadd r2, r0, r5 ; nop // pm = 0, sf = 0, ws = 0 - 0x100208e7019e7340, // ; fadd r3, r1, r5 ; nop // pm = 0, sf = 0, ws = 0 - 0x10020e67159e7480, // ; mov tmu0_t, r2 ; nop // pm = 0, sf = 0, ws = 0 - 0x10020e27159e76c0, // ; mov tmu0_s, r3 ; nop // pm = 0, sf = 0, ws = 0 - 0xa00009e7009e7000, // ldtmu0 ; nop ; nop - 0x30020ba7159e7900, // thrend ; mov tlb_colour, r4 ; nop // pm = 0, sf = 0, ws = 0 - 0x100009e7009e7000, // ; nop ; nop - 0x500009e7009e7000, // sbdone ; nop ; nop -#else - 0xd1724823958e0dbf, // loadsm ; mov r0, varying ; mov r3.8d, 1.0 // pm = 1, sf = 0, ws = 0 - 0x10024821818e7176, // ; fadd r0, r0, r5 ; mov r1, varying // pm = 0, sf = 0, ws = 0 - 0x40024862818e7376, // sbwait ; fadd r1, r1, r5 ; mov r2, varying // pm = 0, sf = 0, ws = 0 - 0x114248a3819e7540, // ; fadd r2, r2, r5 ; mov r3.8a, r0 // pm = 1, sf = 0, ws = 0 - 0x115049e3809e7009, // ; nop ; mov r3.8b, r1 // pm = 1, sf = 0, ws = 0 - 0x116049e3809e7012, // ; nop ; mov r3.8c, r2 // pm = 1, sf = 0, ws = 0 - 0x30020ba7159e76c0, // thrend ; mov tlb_colour, r3 ; nop // pm = 0, sf = 0, ws = 0 - 0x100009e7009e7000, // ; nop ; nop - 0x500009e7009e7000, // sbdone ; nop ; nop -#endif // USE_TEX - }; - memcpy((void *)p,(void *)fs, sizeof(fs)); - -// VS - p = list + offsets[BO_VS]; - uint64_t vs[] = { -#if USE_TEX - 0xe0020c6700601a00, // ldi ; mov vr_setup, 0x00601a00 -#else - 0xe0020c6700701a00, // ldi ; mov vr_setup, 0x00701a00 -#endif // USE_TEX - 0xe0021c6700001a00, // ldi ; mov vw_setup, 0x00001a00 - 0x1002082715c27d80, // ; mov r0, vpm ; nop // pm = 0, sf = 0, ws = 0 - 0x1002086715c27d80, // ; mov r1, vpm ; nop // pm = 0, sf = 0, ws = 0 - 0x100200a715c27d80, // ; mov ra2, vpm ; nop // pm = 0, sf = 0, ws = 0 - 0x100200e715c27d80, // ; mov ra3, vpm ; nop // pm = 0, sf = 0, ws = 0 - 0x100059c020827006, // ; nop ; fmul ra0, r0, uniform // pm = 0, sf = 0, ws = 1 - 0x100059c12082700e, // ; nop ; fmul ra1, r1, uniform // pm = 0, sf = 0, ws = 1 - 0x1012012707027d80, // ; ftoi ra4.16a, ra0, ra0 ; nop // pm = 0, sf = 0, ws = 0 - 0x1022012707067d80, // ; ftoi ra4.16b, ra1, ra1 ; nop // pm = 0, sf = 0, ws = 0 - 0x1002016715c27d80, // ; mov ra5, vpm ; nop // pm = 0, sf = 0, ws = 0 - 0x100201a715c27d80, // ; mov ra6, vpm ; nop // pm = 0, sf = 0, ws = 0 -#if USE_TEX - -#else - 0x100201e715c27d80, // ; mov ra7, vpm ; nop // pm = 0, sf = 0, ws = 0 -#endif // USE_TEX - 0x10020c2715127d80, // ; mov vpm, ra4 ; nop // pm = 0, sf = 0, ws = 0 - 0x10020c27150a7d80, // ; mov vpm, ra2 ; nop // pm = 0, sf = 0, ws = 0 - 0x10020c27150e7d80, // ; mov vpm, ra3 ; nop // pm = 0, sf = 0, ws = 0 - 0x10020c2715167d80, // ; mov vpm, ra5 ; nop // pm = 0, sf = 0, ws = 0 - 0x10020c27151a7d80, // ; mov vpm, ra6 ; nop // pm = 0, sf = 0, ws = 0 -#if USE_TEX - -#else - 0x10020c27151e7d80, // ; mov vpm, ra7 ; nop // pm = 0, sf = 0, ws = 0 -#endif // USE_TEX - 0x300009e7009e7000, // thrend ; nop ; nop - 0x100009e7009e7000, // ; nop ; nop - 0x100009e7009e7000, // ; nop ; nop - }; - memcpy((void *)p,(void *)vs, sizeof(vs)); - -// CS - p = list + offsets[BO_CS]; - uint64_t cs[] = - { -#if USE_TEX - 0xe0020c6700601a00, // ldi ; mov vr_setup, 0x00601a00 -#else - 0xe0020c6700701a00, // ldi ; mov vr_setup, 0x00701a00 -#endif // USE_TEX - 0xe0021c6700001a00, // ldi ; mov vw_setup, 0x00001a00 - 0x1002082715c27d80, // ; mov r0, vpm ; nop // pm = 0, sf = 0, ws = 0 - 0x1002086715c27d80, // ; mov r1, vpm ; nop // pm = 0, sf = 0, ws = 0 - 0x100200a715c27d80, // ; mov ra2, vpm ; nop // pm = 0, sf = 0, ws = 0 - 0x100200e715c27d80, // ; mov ra3, vpm ; nop // pm = 0, sf = 0, ws = 0 - 0x100059c020827006, // ; nop ; fmul ra0, r0, uniform // pm = 0, sf = 0, ws = 1 - 0x100059c12082700e, // ; nop ; fmul ra1, r1, uniform // pm = 0, sf = 0, ws = 1 - 0x1012012707027d80, // ; ftoi ra4.16a, ra0, ra0 ; nop // pm = 0, sf = 0, ws = 0 - 0x1022012707067d80, // ; ftoi ra4.16b, ra1, ra1 ; nop // pm = 0, sf = 0, ws = 0 - 0x1002016715c27d80, // ; mov ra5, vpm ; nop // pm = 0, sf = 0, ws = 0 - 0x100201a715c27d80, // ; mov ra6, vpm ; nop // pm = 0, sf = 0, ws = 0 -#if USE_TEX - -#else - 0x100201e715c27d80, // ; mov ra7, vpm ; nop // pm = 0, sf = 0, ws = 0 -#endif // USE_TEX - 0x10020c27159e7000, // ; mov vpm, r0 ; nop // pm = 0, sf = 0, ws = 0 - 0x10020c27159e7240, // ; mov vpm, r1 ; nop // pm = 0, sf = 0, ws = 0 - 0x10020c27150a7d80, // ; mov vpm, ra2 ; nop // pm = 0, sf = 0, ws = 0 - 0x10020c27150e7d80, // ; mov vpm, ra3 ; nop // pm = 0, sf = 0, ws = 0 - 0x10020c2715127d80, // ; mov vpm, ra4 ; nop // pm = 0, sf = 0, ws = 0 - 0x10020c27150a7d80, // ; mov vpm, ra2 ; nop // pm = 0, sf = 0, ws = 0 - 0x10020c27150e7d80, // ; mov vpm, ra3 ; nop // pm = 0, sf = 0, ws = 0 - 0x300009e7009e7000, // thrend ; nop ; nop - 0x100009e7009e7000, // ; nop ; nop - 0x100009e7009e7000, // ; nop ; nop - }; - - memcpy((void *)p, (void *)cs, sizeof(cs)); - -// Render control list - p = list + offsets[BO_RCL]; - - // Clear color - addbyte(&p, 114); - addword(&p, 0xffffffff); // Opaque White - addword(&p, 0xffffffff); // 32 bit clear colours need to be repeated twice - addword(&p, 0); // Z/vg - addbyte(&p, 0); // stencil - - // Tile Rendering Mode Configuration - addbyte(&p, 113); - addword(&p, bus_addr + offsets[BO_FB]); // framebuffer addresss - addshort(&p, screen_x); // width - addshort(&p, screen_y); // height - addbyte(&p, 0x04); // framebuffer mode (linear rgba8888) - addbyte(&p, 0x00); - - // Do a store of the first tile to force the tile buffer to be cleared - // Tile Coordinates - addbyte(&p, 115); - addbyte(&p, 0); - addbyte(&p, 0); - - // Store Tile Buffer General - addbyte(&p, 28); - addshort(&p, 0); // Store nothing (just clear) - addword(&p, 0); // no address is needed - - // Link all binned lists together - for(int x = 0; x < tile_x ; x++) { - for(int y = 0; y < tile_y ; y++) { - - // Tile Coordinates - addbyte(&p, 115); - addbyte(&p, x); - addbyte(&p, y); - - // Call Tile sublist - addbyte(&p, 17); - addword(&p, bus_addr + offsets[BO_TA] + ((y * tile_x) + x) * 32); - - // Last tile needs a special store instruction - if((x == (tile_x - 1)) && (y == (tile_y - 1))) { - // Store resolved tile color buffer and signal end of frame - addbyte(&p, 25); - } else { - // Store resolved tile color buffer - addbyte(&p, 24); - } - } - } - - int render_length = p - (list + offsets[BO_RCL]); - -// Run our control list - printf("screen_x = %d, screen_y = %d\n", screen_x, screen_y); - printf("tile_x = %d, tile_y = %d\n", tile_x, tile_y); - printf("list = 0x%08x\n", list); - printf("\n"); - -// Clear all perf counter. - v3d[V3D_PCTRC] = 0xffff; -// enable all perf counter. - v3d[V3D_PCTRE] = 0xffff; - assert((v3d[V3D_PCTRE] & 0xffff) == 0xffff); - - printf("Binner control list constructed\n"); - printf("Start Address: 0x%08x, length: 0x%x\n", bus_addr, length); - - v3d[V3D_CT0CS] = 0x30; - while(v3d[V3D_CT0CS] & 0x20); - - v3d[V3D_L2CACTL] = 0x4; - v3d[V3D_CT0CA] = bus_addr; - v3d[V3D_CT0EA] = bus_addr + length; - printf("V3D_CT0CS: 0x%08x, CA: 0x%08x\n", v3d[V3D_CT0CS], v3d[V3D_CT0CA]); - printf("V3D_CT0CS: 0x%08x, EA: 0x%08x\n", v3d[V3D_CT0CS], v3d[V3D_CT0EA]); - - // Wait for control list to execute - while(v3d[V3D_CT0CS] & 0x20); - - v3d[V3D_CT0CS] = 0x20; - printf("V3D_CT0CS: 0x%08x, CA: 0x%08x\n", v3d[V3D_CT0CS], v3d[V3D_CT0CA]); - printf("V3D_CT0CS: 0x%08x, EA: 0x%08x\n", v3d[V3D_CT0CS], v3d[V3D_CT0EA]); - printf("\n"); - - v3d[V3D_L2CACTL] = 0x4; - - printf("Render control list constructed\n"); - printf("Start Address: 0x%08x, length: 0x%x\n", bus_addr + 0xe200, render_length); - - v3d[V3D_CT1CS] = 0x30; - while(v3d[V3D_CT1CS] & 0x20); - - v3d[V3D_L2CACTL] = 0x4; - v3d[V3D_CT1CA] = bus_addr + 0xe200; - v3d[V3D_CT1EA] = bus_addr + 0xe200 + render_length; - - printf("V3D_CT1CS: 0x%08x, CA: 0x%08x\n", v3d[V3D_CT1CS], v3d[V3D_CT1CA]); - printf("V3D_CT1CS: 0x%08x, EA: 0x%08x\n", v3d[V3D_CT1CS], v3d[V3D_CT1EA]); - - while(v3d[V3D_CT1CS] & 0x20); - - v3d[V3D_CT1CS] = 0x20; - printf("V3D_CT1CS: 0x%08x, CA: 0x%08x\n", v3d[V3D_CT1CS], v3d[V3D_CT1CA]); - printf("V3D_CT1CS: 0x%08x, EA: 0x%08x\n", v3d[V3D_CT1CS], v3d[V3D_CT1EA]); - printf("\n"); - - v3d[V3D_L2CACTL] = 0x4; - -// Dump tile allocation memory - printf("Dump tile allocation memory\n"); - for (int x = 0; x < tile_x; x++) { - for (int y = 0; y < tile_y; y++) { - int *p = (int *)(list + offsets[BO_TA] + (((y * tile_x) + x) * 32)); - for (int z = 0; z < 32 / 4; z++) { - printf("0x%08x ", *p); p++; - } - printf("\n"); - } - } - printf("\n"); - printf("V3D_PCTR9: %d\n", v3d[V3D_PCTR9]); - printf("V3D_PCTR10: %d\n", v3d[V3D_PCTR10]); - printf("V3D_PCTR14: %d\n", v3d[V3D_PCTR14]); - printf("V3D_PCTR15: %d\n", v3d[V3D_PCTR15]); - printf("\n"); - printf("V3D_DBGE: 0x%08x\n", v3d[V3D_DBGE]); - printf("V3D_FDBGO: 0x%08x\n", v3d[V3D_FDBGO]); - printf("V3D_FDBGB: 0x%08x\n", v3d[V3D_FDBGR]); - printf("V3D_FDBGR: 0x%08x\n", v3d[V3D_FDBGB]); - printf("V3D_FDBGS: 0x%08x\n", v3d[V3D_FDBGS]); - printf("\n"); - printf("V3D_ERRSTAT: 0x%08x\n", v3d[V3D_ERRSTAT]); - -// Disable perf counter - v3d[V3D_PCTRE] = 0; - - SaveBMP("./frame.bmp", list + offsets[BO_FB]); - printf("frame buffer memory dumpped to frame.data\n"); - -// Release resources - unmapmem((void *) list, offsets[BO_TOTAL]); - mem_unlock(mbox, handle); - mem_free(mbox, handle); - - printf("done\n"); -} - -int main(int argc, char **argv) { - mbox = mbox_open(); - - // The blob now has this nice handy call which powers up the v3d pipeline. - qpu_enable(mbox, 1); - - // map v3d's registers into our address space. - v3d = (unsigned *) mapmem(0x3fc00000, 0x1000); - - printf("v3d = 0x%x\n", (int)v3d); - printf("v3d[V3D_IDENT0] = 0x%x\n", v3d[V3D_IDENT0]); - - if(v3d[V3D_IDENT0] != 0x02443356) { // Magic number. - printf("Error: V3D pipeline isn't powered up and accessable.\n"); - exit(-1); - } - - // We now have access to the v3d registers, we should do something. - testTriangle(); - - unmapmem((void *) v3d, 0x1000); - qpu_enable(mbox, 0); - mbox_close(mbox); - - return 0; -} - - - - - diff --git a/vc4_test/v3d.h b/vc4_test/v3d.h deleted file mode 100644 index 033da07..0000000 --- a/vc4_test/v3d.h +++ /dev/null @@ -1,116 +0,0 @@ -/* -The MIT License (MIT) - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -// Defines for v3d register offsets -#define V3D_IDENT0 (0x000>>2) // V3D Identification 0 (V3D block identity) -#define V3D_IDENT1 (0x004>>2) // V3D Identification 1 (V3D Configuration A) -#define V3D_IDENT2 (0x008>>2) // V3D Identification 1 (V3D Configuration B) - -#define V3D_SCRATCH (0x010>>2) // Scratch Register - -#define V3D_L2CACTL (0x020>>2) // 2 Cache Control -#define V3D_SLCACTL (0x024>>2) // Slices Cache Control - -#define V3D_INTCTL (0x030>>2) // Interrupt Control -#define V3D_INTENA (0x034>>2) // Interrupt Enables -#define V3D_INTDIS (0x038>>2) // Interrupt Disables - -#define V3D_CT0CS (0x100>>2) // Control List Executor Thread 0 Control and Status. -#define V3D_CT1CS (0x104>>2) // Control List Executor Thread 1 Control and Status. -#define V3D_CT0EA (0x108>>2) // Control List Executor Thread 0 End Address. -#define V3D_CT1EA (0x10c>>2) // Control List Executor Thread 1 End Address. -#define V3D_CT0CA (0x110>>2) // Control List Executor Thread 0 Current Address. -#define V3D_CT1CA (0x114>>2) // Control List Executor Thread 1 Current Address. -#define V3D_CT00RA0 (0x118>>2) // Control List Executor Thread 0 Return Address. -#define V3D_CT01RA0 (0x11c>>2) // Control List Executor Thread 1 Return Address. -#define V3D_CT0LC (0x120>>2) // Control List Executor Thread 0 List Counter -#define V3D_CT1LC (0x124>>2) // Control List Executor Thread 1 List Counter -#define V3D_CT0PC (0x128>>2) // Control List Executor Thread 0 Primitive List Counter -#define V3D_CT1PC (0x12c>>2) // Control List Executor Thread 1 Primitive List Counter - -#define V3D_PCS (0x130>>2) // V3D Pipeline Control and Status -#define V3D_BFC (0x134>>2) // Binning Mode Flush Count -#define V3D_RFC (0x138>>2) // Rendering Mode Frame Count - -#define V3D_BPCA (0x300>>2) // Current Address of Binning Memory Pool -#define V3D_BPCS (0x304>>2) // Remaining Size of Binning Memory Pool -#define V3D_BPOA (0x308>>2) // Address of Overspill Binning Memory Block -#define V3D_BPOS (0x30c>>2) // Size of Overspill Binning Memory Block -#define V3D_BXCF (0x310>>2) // Binner Debug - -#define V3D_SQRSV0 (0x410>>2) // Reserve QPUs 0-7 -#define V3D_SQRSV1 (0x414>>2) // Reserve QPUs 8-15 -#define V3D_SQCNTL (0x418>>2) // QPU Scheduler Control - -#define V3D_SRQPC (0x430>>2) // QPU User Program Request Program Address -#define V3D_SRQUA (0x434>>2) // QPU User Program Request Uniforms Address -#define V3D_SRQUL (0x438>>2) // QPU User Program Request Uniforms Length -#define V3D_SRQCS (0x43c>>2) // QPU User Program Request Control and Status - -#define V3D_VPACNTL (0x500>>2) // VPM Allocator Control -#define V3D_VPMBASE (0x504>>2) // VPM base (user) memory reservation - -#define V3D_PCTRC (0x670>>2) // Performance Counter Clear -#define V3D_PCTRE (0x674>>2) // Performance Counter Enables - -#define V3D_PCTR0 (0x680>>2) // Performance Counter Count 0 -#define V3D_PCTRS0 (0x684>>2) // Performance Counter Mapping 0 -#define V3D_PCTR1 (0x688>>2) // Performance Counter Count 1 -#define V3D_PCTRS1 (0x68c>>2) // Performance Counter Mapping 1 -#define V3D_PCTR2 (0x690>>2) // Performance Counter Count 2 -#define V3D_PCTRS2 (0x694>>2) // Performance Counter Mapping 2 -#define V3D_PCTR3 (0x698>>2) // Performance Counter Count 3 -#define V3D_PCTRS3 (0x69c>>2) // Performance Counter Mapping 3 -#define V3D_PCTR4 (0x6a0>>2) // Performance Counter Count 4 -#define V3D_PCTRS4 (0x6a4>>2) // Performance Counter Mapping 4 -#define V3D_PCTR5 (0x6a8>>2) // Performance Counter Count 5 -#define V3D_PCTRS5 (0x6ac>>2) // Performance Counter Mapping 5 -#define V3D_PCTR6 (0x6b0>>2) // Performance Counter Count 6 -#define V3D_PCTRS6 (0x6b4>>2) // Performance Counter Mapping 6 -#define V3D_PCTR7 (0x6b8>>2) // Performance Counter Count 7 -#define V3D_PCTRS7 (0x6bc>>2) // Performance Counter Mapping 7 -#define V3D_PCTR8 (0x6c0>>2) // Performance Counter Count 8 -#define V3D_PCTRS8 (0x6c4>>2) // Performance Counter Mapping 8 -#define V3D_PCTR9 (0x6c8>>2) // Performance Counter Count 9 -#define V3D_PCTRS9 (0x6cc>>2) // Performance Counter Mapping 9 -#define V3D_PCTR10 (0x6d0>>2) // Performance Counter Count 10 -#define V3D_PCTRS10 (0x6d4>>2) // Performance Counter Mapping 10 -#define V3D_PCTR11 (0x6d8>>2) // Performance Counter Count 11 -#define V3D_PCTRS11 (0x6dc>>2) // Performance Counter Mapping 11 -#define V3D_PCTR12 (0x6e0>>2) // Performance Counter Count 12 -#define V3D_PCTRS12 (0x6e4>>2) // Performance Counter Mapping 12 -#define V3D_PCTR13 (0x6e8>>2) // Performance Counter Count 13 -#define V3D_PCTRS13 (0x6ec>>2) // Performance Counter Mapping 13 -#define V3D_PCTR14 (0x6f0>>2) // Performance Counter Count 14 -#define V3D_PCTRS14 (0x6f4>>2) // Performance Counter Mapping 14 -#define V3D_PCTR15 (0x6f8>>2) // Performance Counter Count 15 -#define V3D_PCTRS15 (0x6fc>>2) // Performance Counter Mapping 15 -#define V3D_PCTR16 (0x700>>2) // Performance Counter Count 16 -#define V3D_PCTRS16 (0x704>>2) // Performance Counter Mapping 16 - -#define V3D_DBGE (0xf00>>2) // PSE Error Signals -#define V3D_FDBGO (0xf04>>2) // FEP Overrun Error Signals -#define V3D_FDBGB (0xf08>>2) // FEP Interface Ready and Stall Signals, FEP Busy Signals -#define V3D_FDBGR (0xf0c>>2) // FEP Internal Ready Signals -#define V3D_FDBGS (0xf10>>2) // FEP Internal Stall Input Signals - -#define V3D_ERRSTAT (0xf20>>2) // Miscellaneous Error Signals (VPM, VDW, VCD, VCM, L2C)