Compare commits

...
81 Commits
Author SHA1 Message Date
Bud 5c2de5c5af VRAM Check for dgpus 2024-04-25 04:15:41 +01:00
Bud 39ae925267 commented potential solution for display adapter being defaulted to gpu 0 (igpu) 2024-04-24 10:28:30 +01:00
Mike Rodriguez a342f5f261 Update FUNDING.yml 2024-04-01 03:01:12 -07:00
Mike Rodriguez 6fbe4d0345 Update FUNDING.yml 2024-04-01 02:59:32 -07:00
Mike Rodriguez ddab6332d0 Update FUNDING.yml 2024-04-01 02:58:25 -07:00
Mike Rodriguez 96cd8d9242 Added additional credits: Baloukj, zjoasan, and Bud. 2024-03-30 17:03:55 -07:00
Mike Rodriguez a34825ea76 Driver source update. 2024-03-30 16:45:11 -07:00
Mike Rodriguez 2048024073 Merge pull request #49 from zjoasan/script-ps
Scripts folder, containing toogle-vdd.ps1. Thank you zjoasan.
2024-03-20 01:59:41 -07:00
Mike Rodriguez 6684040dc7 Create FUNDING.yml 2024-03-17 05:17:40 -07:00
Joakim Sandström fe8091828f Update toggle-VDD.ps1
Some code beautification and added self elevation.
2024-03-01 19:45:21 +01:00
Joakim Sandström 074413ce23 Might need privs-elevation 2024-02-25 01:18:01 +01:00
Joakim Sandström ac6a93486a using device id 2024-02-24 23:23:35 +01:00
Joakim Sandström 321781bdb0 first Toogle-script 2024-02-24 18:41:55 +01:00
Bud ce92f44f69 Merge pull request #46 from zjoasan/zjoasan-README-patch
Update README.md
2024-02-16 12:20:03 +00:00
Bud 6144b56d27 Update README.md 2024-02-16 01:28:22 +00:00
Joakim Sandström c4e01ba39e Update README.md
Added some info about how to uninstall, and added a Ps. in the end of installation, about the importance of options.txt being located in the right folder.
2024-02-16 00:03:29 +01:00
Mike Rodriguez be3f0a6288 Merge pull request #11 from zjoasan/master
Update IddSampleDriver.inf with new Manufacturer/Device Name
2023-12-05 10:10:35 -08:00
Joakim Sandström c44b310a55 Update IddSampleDriver.inf
Changed manufacturer and Device-name
2023-12-04 19:08:35 +01:00
Mike Rodriguez 6058ce0b6e Update README.md 2023-12-03 18:36:11 -08:00
Mike Rodriguez 9d9d8d3e4e Update README.md 2023-12-02 17:36:31 -08:00
Mike Rodriguez 929d970f20 Update README.md 2023-12-02 17:35:20 -08:00
Mike Rodriguez d4833be7f4 Update README.md 2023-12-02 17:34:53 -08:00
Mike Rodriguez 3778c78bf6 Update README.md 2023-12-02 08:59:22 -08:00
Mike Rodriguez 227c69bb69 Update README.md 2023-12-02 08:59:08 -08:00
Mike Rodriguez 3600ea4f93 Update README.md 2023-12-02 08:05:43 -08:00
Mike Rodriguez 2a7a4cfe30 Moved Installer to new repo. 2023-12-02 07:18:36 -08:00
Mike Rodriguez c9bff80b23 HDR Support. 2023-12-02 07:18:11 -08:00
Mike Rodriguez 4a1649b197 Update README.md 2023-12-02 06:32:40 -08:00
Mike Rodriguez 2ac6924bc2 Update README.md 2023-12-02 06:24:33 -08:00
Mike Rodriguez 4d4d0a7377 Refresh rate bug fix. Initial implementation.
Initial attempt to fix broken refresh rates. All resolutions should now work with all refresh rates. Some resolutions may use a higher signal mode to accommodate, but the desktop resolution will remain correct. Working to align all active signals and desktop signals.
2023-10-21 11:28:06 -07:00
Mike Rodriguez dfe1ef953a Update README.md 2023-10-20 01:46:00 -07:00
Mike Rodriguez 0b76138aae Update README.md 2023-10-20 01:39:43 -07:00
Mike Rodriguez 6388aaaedc Merge branch 'master' of https://github.com/itsmikethetech/Virtual-Display-Driver 2023-10-20 01:38:48 -07:00
Mike Rodriguez 57980ab82c Added 165Hz support. 2023-10-20 01:38:39 -07:00
Mike Rodriguez 5e7773dd93 Update README.md 2023-10-20 01:29:19 -07:00
Mike Rodriguez 566183c8f7 Merge branch 'master' of https://github.com/itsmikethetech/Virtual-Display-Driver 2023-10-20 01:27:24 -07:00
Mike Rodriguez 6e84c52109 Added new refresh rates.
Added support for 30hz, 480hz, and 500hz.
2023-10-20 01:27:16 -07:00
Mike Rodriguez fc70569f4b Update README.md 2023-10-20 01:20:55 -07:00
Mike Rodriguez c696867321 Added new widescreen resolutions.
Added support for:
2732 x 2048
2560 x 1080
2880 x 1200
3440 x 1440
3840 x 1600
4320 x 1800
5120 x 2160
5760 x 2400
6880 x 2880
7680 x 3200
8640 x 3600
10240 x 432
2880 x 900
3840 x 1080
3840 x 1200
4320 x 1200
5120 x 1440
5120 x 1600
5760 x 1600
5760 x 1800
6400 x 1800
6480 x 1800
7680 x 2160
7680 x 2400
8640 x 2400
2388 x 1668
2400 x 1080
3456 x 2234
3456 x 2234
2023-10-20 01:18:57 -07:00
Mike Rodriguez 06bc23160b Added 2732 x 2048 support. 2023-10-19 00:12:42 -07:00
Mike Rodriguez 23405e5e35 Added 2732 x 2048 support. 2023-10-19 00:10:31 -07:00
Mike Rodriguez 655cf45e33 Update README.md 2023-10-18 19:51:54 -07:00
Mike Rodriguez b0af9c5d14 Update README.md 2023-10-18 17:07:37 -07:00
Mike Rodriguez 802667e7bc KMDOD early sample. Not complete. 2023-10-18 17:06:02 -07:00
Mike Rodriguez 953f6941ea Merge branch 'master' of https://github.com/itsmikethetech/Virtual-Display-Driver 2023-10-18 16:46:02 -07:00
Mike Rodriguez 963c13ee28 Added initial custom EDID for KMDOD driver. 2023-10-18 16:45:53 -07:00
Mike Rodriguez fb1dc70865 Update README.md 2023-10-18 16:36:55 -07:00
Mike Rodriguez 64e6994229 Update README.md 2023-10-18 16:36:15 -07:00
Mike Rodriguez 9786e055c4 Update README.md 2023-10-18 16:35:33 -07:00
Mike Rodriguez 2cd34bc148 Update README.md 2023-10-18 16:32:36 -07:00
Mike Rodriguez 4b3c17838b Update README.md 2023-10-18 16:31:31 -07:00
Mike Rodriguez 27274fc582 Added beta installer source. Not complete. 2023-10-18 16:20:03 -07:00
Mike Rodriguez 6e978fff57 Added installer source.
Not ready for use.
2023-10-18 16:07:33 -07:00
Mike Rodriguez 10ab460cdf Added beta installer source. Not complete. 2023-10-18 16:05:26 -07:00
Mike Rodriguez 69c1262183 Update README.md 2023-10-14 18:48:04 -07:00
Mike Rodriguez 236b8d0abe Update README.md 2023-10-14 18:39:24 -07:00
Mike Rodriguez 9ee885a997 Update README.md 2023-10-14 18:38:11 -07:00
Mike Rodriguez 280d9a8453 Update README.md 2023-10-14 12:31:46 -07:00
Mike Rodriguez 9dc77543ed Merge branch 'master' of https://github.com/itsmikethetech/Virtual-Display-Driver 2023-10-14 12:30:15 -07:00
Mike Rodriguez cecb3d7090 Added support for more refresh rates. 2023-10-14 12:30:05 -07:00
Mike Rodriguez 34d6ac026c Update README.md 2023-10-14 12:29:31 -07:00
Mike Rodriguez 4c5d820530 Update README.md
Added support for 75hz, 144hz, and 240hz.
2023-10-14 12:27:47 -07:00
Mike Rodriguez 8140f98bd5 Update README.md 2023-10-14 12:10:40 -07:00
Mike Rodriguez abf90476bf Update README.md 2023-10-14 12:08:25 -07:00
Mike Rodriguez 111e2f0cfa Update README.md 2023-10-14 12:08:00 -07:00
Mike Rodriguez 29e50367d8 Update README.md 2023-10-14 11:33:47 -07:00
Mike Rodriguez c7a7f82ff5 Update README.md 2023-10-14 11:32:27 -07:00
Mike Rodriguez 2d9f7d04de Update README.md 2023-10-14 11:31:39 -07:00
Mike Rodriguez be0df76fc3 Merge branch 'master' of https://github.com/itsmikethetech/Virtual-Display-Driver 2023-10-14 11:04:30 -07:00
Mike Rodriguez 7de73dcf49 Updated Driver 2023-10-14 11:03:24 -07:00
Mike Rodriguez ef4e93fcf8 Update readme.md 2023-10-14 09:53:09 -07:00
Mike Rodriguez a8f975ca17 Update IddSampleDriver.inf 2023-10-14 07:00:22 -07:00
Mike Rodriguez 33349dd03f Update IddSampleDriver.sln 2023-10-14 06:58:44 -07:00
Mike Rodriguez 000d024827 Update README.md 2023-10-14 06:57:26 -07:00
Mike Rodriguez 09e1f9c537 Update README.md 2023-10-14 06:55:00 -07:00
Mike Rodriguez 4665af1c15 Update README.md 2023-10-14 06:54:42 -07:00
Mike Rodriguez d22225f071 Update README.md 2023-10-14 06:48:55 -07:00
Mike Rodriguez 5c242a86bb Update README.md 2023-10-14 06:47:32 -07:00
Mike Rodriguez 3ebd8be904 Merge branch 'master' of https://github.com/itsmikethetech/IddSampleDriver 2023-10-14 06:01:29 -07:00
Mike Rodriguez eb31a83dd8 Limit to 60 and 120hz. 2023-10-14 06:01:20 -07:00
Mike Rodriguez 1d5f7a7c58 Update README.md 2023-10-14 06:00:46 -07:00
25 changed files with 5632 additions and 643 deletions

No files matched your search

+3
View File
@@ -0,0 +1,3 @@
# These are supported funding model platforms
github: [itsmikethetech, zjoasan, bud3699]
BIN
View File
Binary file not shown.
+671 -444
View File
File diff suppressed because it is too large. Load diff
Binary file not shown.
+2 -3
View File
@@ -1,7 +1,7 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.31129.286
# Visual Studio Version 17
VisualStudioVersion = 17.9.34622.214
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "IddSampleDriver", "IddSampleDriver.vcxproj", "{2D54CB75-8B17-4F11-97DC-847B0244CD46}"
EndProject
@@ -37,7 +37,6 @@ Global
{2D54CB75-8B17-4F11-97DC-847B0244CD46}.Release|ARM64.Deploy.0 = Release|ARM64
{2D54CB75-8B17-4F11-97DC-847B0244CD46}.Release|x64.ActiveCfg = Release|x64
{2D54CB75-8B17-4F11-97DC-847B0244CD46}.Release|x64.Build.0 = Release|x64
{2D54CB75-8B17-4F11-97DC-847B0244CD46}.Release|x64.Deploy.0 = Release|x64
{2D54CB75-8B17-4F11-97DC-847B0244CD46}.Release|x86.ActiveCfg = Release|Win32
{2D54CB75-8B17-4F11-97DC-847B0244CD46}.Release|x86.Build.0 = Release|Win32
{2D54CB75-8B17-4F11-97DC-847B0244CD46}.Release|x86.Deploy.0 = Release|Win32
+14 -2
View File
@@ -38,6 +38,9 @@
<ClCompile Include="Driver.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\..\..\Downloads\wudfwdm.h">
<DeploymentContent>true</DeploymentContent>
</ClInclude>
<ClInclude Include="Driver.h" />
<ClInclude Include="Trace.h" />
</ItemGroup>
@@ -116,8 +119,9 @@
<UMDF_VERSION_MAJOR>2</UMDF_VERSION_MAJOR>
<IndirectDisplayDriver>true</IndirectDisplayDriver>
<IDDCX_VERSION_MAJOR>1</IDDCX_VERSION_MAJOR>
<IDDCX_VERSION_MINOR>0</IDDCX_VERSION_MINOR>
<IDDCX_VERSION_MINOR>10</IDDCX_VERSION_MINOR>
<Driver_SpectreMitigation>Spectre</Driver_SpectreMitigation>
<UMDF_VERSION_MINOR>25</UMDF_VERSION_MINOR>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<TargetVersion>Windows10</TargetVersion>
@@ -125,7 +129,9 @@
<UMDF_VERSION_MAJOR>2</UMDF_VERSION_MAJOR>
<IndirectDisplayDriver>true</IndirectDisplayDriver>
<IDDCX_VERSION_MAJOR>1</IDDCX_VERSION_MAJOR>
<IDDCX_VERSION_MINOR>0</IDDCX_VERSION_MINOR>
<IDDCX_VERSION_MINOR>10</IDDCX_VERSION_MINOR>
<Driver_SpectreMitigation>Spectre</Driver_SpectreMitigation>
<UMDF_VERSION_MINOR>25</UMDF_VERSION_MINOR>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'" Label="Configuration">
<TargetVersion>Windows10</TargetVersion>
@@ -178,6 +184,7 @@
<DebuggerFlavor>DbgengRemoteDebugger</DebuggerFlavor>
<RunCodeAnalysis>true</RunCodeAnalysis>
<Inf2CatUseLocalTime>true</Inf2CatUseLocalTime>
<TimeStampServer />
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<DebuggerFlavor>DbgengRemoteDebugger</DebuggerFlavor>
@@ -231,10 +238,14 @@
<WppScanConfigurationData Condition="'%(ClCompile.ScanConfigurationData)' == ''">trace.h</WppScanConfigurationData>
<ExceptionHandling>Async</ExceptionHandling>
<EnablePREfast>true</EnablePREfast>
<AdditionalOptions>/D_ATL_NO_WIN_SUPPORT /DUMDF_DRIVER /DIDDCX_VERSION_MAJOR=1 /DIDDCX_VERSION_MINOR=4 /DIDDCX_MINIMUM_VERSION_REQUIRED=4 %(AdditionalOptions)</AdditionalOptions>
</ClCompile>
<Link>
<AdditionalDependencies>%(AdditionalDependencies);OneCoreUAP.lib;avrt.lib</AdditionalDependencies>
</Link>
<DriverSign>
<FileDigestAlgorithm>SHA1</FileDigestAlgorithm>
</DriverSign>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
@@ -243,6 +254,7 @@
<WppScanConfigurationData Condition="'%(ClCompile.ScanConfigurationData)' == ''">trace.h</WppScanConfigurationData>
<ExceptionHandling>Async</ExceptionHandling>
<EnablePREfast>true</EnablePREfast>
<AdditionalOptions>/D_ATL_NO_WIN_SUPPORT /DUMDF_DRIVER /DIDDCX_VERSION_MAJOR=1 /DIDDCX_VERSION_MINOR=10 /DIDDCX_MINIMUM_VERSION_REQUIRED=3 %(AdditionalOptions)</AdditionalOptions>
</ClCompile>
<Link>
<AdditionalDependencies>%(AdditionalDependencies);OneCoreUAP.lib;avrt.lib</AdditionalDependencies>
@@ -30,6 +30,9 @@
<ClInclude Include="Trace.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\Downloads\wudfwdm.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="Driver.cpp">
+28
View File
@@ -0,0 +1,28 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2013
VisualStudioVersion = 12.0
MinimumVisualStudioVersion = 12.0
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SampleDisplay", "Sample\SampleDisplay.vcxproj", "{D3C62015-3845-4DA8-8522-5DC45B735063}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Release|Win32 = Release|Win32
Debug|x64 = Debug|x64
Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{D3C62015-3845-4DA8-8522-5DC45B735063}.Debug|Win32.ActiveCfg = Debug|Win32
{D3C62015-3845-4DA8-8522-5DC45B735063}.Debug|Win32.Build.0 = Debug|Win32
{D3C62015-3845-4DA8-8522-5DC45B735063}.Release|Win32.ActiveCfg = Release|Win32
{D3C62015-3845-4DA8-8522-5DC45B735063}.Release|Win32.Build.0 = Release|Win32
{D3C62015-3845-4DA8-8522-5DC45B735063}.Debug|x64.ActiveCfg = Debug|x64
{D3C62015-3845-4DA8-8522-5DC45B735063}.Debug|x64.Build.0 = Debug|x64
{D3C62015-3845-4DA8-8522-5DC45B735063}.Release|x64.ActiveCfg = Release|x64
{D3C62015-3845-4DA8-8522-5DC45B735063}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal
+71
View File
@@ -0,0 +1,71 @@
### THIS SAMPLE IS INCOMPLETE - Currently a Work in Progress attempt at HDR and 10-bit video support.
---
page_type: sample
description: "Implements most DDIs that a display-only miniport driver should provide to the Windows Display Driver Model (WDDM)."
languages:
- cpp
products:
- windows
- windows-wdk
---
# Kernel mode display-only miniport driver (KMDOD) sample
The kernel mode display-only miniport driver (KMDOD) sample implements most of the device driver interfaces (DDIs) that a display-only miniport driver should provide to the Windows Display Driver Model (WDDM). The code is useful to understand how to write a miniport driver for a display-only device, or how to develop a full WDDM driver.
For more info on WDDM drivers, see [Windows Display Driver Model (WDDM) Design Guide](https://docs.microsoft.com/windows-hardware/drivers/display/windows-vista-display-driver-model-design-guide).
This code can also help you to understand the use and implementation of display-related DDIs. The INF file shows how to make a display miniport driver visible to other WDDM components.
The sample can be installed on top of a VESA-capable graphics adapter, or on top of a graphics device that supports access to frame buffer memory through the Unified Extensible Firmware Interface (UEFI).
The sample driver does not support the *sleep* power state. If it is placed in the sleep state, the driver will cause a system bugcheck to occur. There is no workaround available, by design.
If the current display driver is not a WDDM 1.2 compliant driver, the sample driver might fail to install, with error code 43 displayed. The KMDOD driver is actually installed, but it cannot be started. The workaround for this issue is to switch to the Microsoft Basic Display Adapter Driver before installing the KMDOD sample driver, or simply to reboot your system after installing the KMDOD sample.
## Installation
In Microsoft Visual Studio, press **F5** to build the sample and then deploy it to a target machine. For more info, see [Deploying a Driver to a Test Computer](https://docs.microsoft.com/windows-hardware/drivers/develop/deploying-a-driver-to-a-test-computer).
In some cases you might need to install the driver manually, as follows.
1. Add the following files to the directory given by ...\\[x64]\\C++\\Package:
- SampleDriver.cat
- SampleDriver.inf
- SampleDriver.sys
- SampleDriver.cer
1. Unless you've provided a production certificate, you should manually install the SampleDriver.cer digital certificate with the following command:
`Certutil.exe -addstore root SampleDriver.cer`
1. Then enable test signing by running the following BCDEdit command:
`Bcdedit.exe -set TESTSIGNING ON`
> [!NOTE]
> After you change the TESTSIGNING boot configuration option, restart the computer for the change to take effect.
For more info, see [The TESTSIGNING Boot Configuration Option](https://docs.microsoft.com/windows-hardware/drivers/install/the-testsigning-boot-configuration-option).
1. Manually install the driver using Device Manager, which is available from Control Panel.
### ACPI-based GPUs
To install the KMDOD sample driver on a GPU that is an Advanced Configuration and Power Interface (ACPI) device, add these lines to the `[MS]`, `[MS.NTamd64]`, and `[MS.NTarm]` sections of the Sampledisplay.inf file:
```inf
Text
" Kernel mode display only sample driver " = KDODSamp_Inst, ACPI\CLS_0003&SUBCLS_0000
" Kernel mode display only sample driver " = KDODSamp_Inst, ACPI\CLS_0003&SUBCLS_0001
" Kernel mode display only sample driver " = KDODSamp_Inst, ACPI\CLS_0003&SUBCLS_0003
```
This new code provides generic identifiers for ACPI hardware.
You can optionally delete the original lines of code within these sections of the INF file.
+209
View File
@@ -0,0 +1,209 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{D3C62015-3845-4DA8-8522-5DC45B735063}</ProjectGuid>
<RootNamespace>$(MSBuildProjectName)</RootNamespace>
<Configuration Condition="'$(Configuration)' == ''">Debug</Configuration>
<Platform Condition="'$(Platform)' == ''">Win32</Platform>
<SampleGuid>{4E49D9DD-F772-41AD-9367-F225BF8261D3}</SampleGuid>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<TargetVersion>Windows10</TargetVersion>
<UseDebugLibraries>False</UseDebugLibraries>
<DriverTargetPlatform>Universal</DriverTargetPlatform>
<DriverType>WDM</DriverType>
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
<ConfigurationType>Driver</ConfigurationType>
</PropertyGroup>
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<TargetVersion>Windows10</TargetVersion>
<UseDebugLibraries>True</UseDebugLibraries>
<DriverTargetPlatform>Universal</DriverTargetPlatform>
<DriverType>WDM</DriverType>
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
<ConfigurationType>Driver</ConfigurationType>
</PropertyGroup>
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<TargetVersion>Windows10</TargetVersion>
<UseDebugLibraries>False</UseDebugLibraries>
<DriverTargetPlatform>Universal</DriverTargetPlatform>
<DriverType>WDM</DriverType>
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
<ConfigurationType>Driver</ConfigurationType>
</PropertyGroup>
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<TargetVersion>Windows10</TargetVersion>
<UseDebugLibraries>True</UseDebugLibraries>
<DriverTargetPlatform>Universal</DriverTargetPlatform>
<DriverType>WDM</DriverType>
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
<ConfigurationType>Driver</ConfigurationType>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<PropertyGroup>
<OutDir>$(IntDir)</OutDir>
</PropertyGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
</ImportGroup>
<ItemGroup Label="WrappedTaskItems" />
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Link>
<AdditionalDependencies>%(AdditionalDependencies);$(DDK_LIB_PATH)\displib.lib;$(DDK_LIB_PATH)\ntoskrnl.lib</AdditionalDependencies>
</Link>
<ResourceCompile>
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);$(SDK_INC_PATH)</AdditionalIncludeDirectories>
</ResourceCompile>
<ClCompile>
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);$(SDK_INC_PATH)</AdditionalIncludeDirectories>
</ClCompile>
<Midl>
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);$(SDK_INC_PATH)</AdditionalIncludeDirectories>
</Midl>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Link>
<AdditionalDependencies>%(AdditionalDependencies);$(DDK_LIB_PATH)\displib.lib;$(DDK_LIB_PATH)\ntoskrnl.lib</AdditionalDependencies>
</Link>
<ResourceCompile>
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);$(SDK_INC_PATH)</AdditionalIncludeDirectories>
</ResourceCompile>
<ClCompile>
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);$(SDK_INC_PATH)</AdditionalIncludeDirectories>
</ClCompile>
<Midl>
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);$(SDK_INC_PATH)</AdditionalIncludeDirectories>
</Midl>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Link>
<AdditionalDependencies>%(AdditionalDependencies);$(DDK_LIB_PATH)\displib.lib;$(DDK_LIB_PATH)\ntoskrnl.lib</AdditionalDependencies>
</Link>
<ResourceCompile>
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);$(SDK_INC_PATH)</AdditionalIncludeDirectories>
</ResourceCompile>
<ClCompile>
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);$(SDK_INC_PATH)</AdditionalIncludeDirectories>
</ClCompile>
<Midl>
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);$(SDK_INC_PATH)</AdditionalIncludeDirectories>
</Midl>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Link>
<AdditionalDependencies>%(AdditionalDependencies);$(DDK_LIB_PATH)\displib.lib;$(DDK_LIB_PATH)\ntoskrnl.lib</AdditionalDependencies>
</Link>
<ResourceCompile>
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);$(SDK_INC_PATH)</AdditionalIncludeDirectories>
</ResourceCompile>
<ClCompile>
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);$(SDK_INC_PATH)</AdditionalIncludeDirectories>
</ClCompile>
<Midl>
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);$(SDK_INC_PATH)</AdditionalIncludeDirectories>
</Midl>
</ItemDefinitionGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<TargetName>SampleDisplay</TargetName>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<TargetName>SampleDisplay</TargetName>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<TargetName>SampleDisplay</TargetName>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<TargetName>SampleDisplay</TargetName>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level4</WarningLevel>
<ExceptionHandling>
</ExceptionHandling>
</ClCompile>
<DriverSign>
<FileDigestAlgorithm>sha256</FileDigestAlgorithm>
</DriverSign>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<WarningLevel>Level4</WarningLevel>
<ExceptionHandling>
</ExceptionHandling>
</ClCompile>
<DriverSign>
<FileDigestAlgorithm>sha256</FileDigestAlgorithm>
</DriverSign>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level4</WarningLevel>
<ExceptionHandling>
</ExceptionHandling>
</ClCompile>
<DriverSign>
<FileDigestAlgorithm>sha256</FileDigestAlgorithm>
</DriverSign>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<WarningLevel>Level4</WarningLevel>
<ExceptionHandling>
</ExceptionHandling>
</ClCompile>
<DriverSign>
<FileDigestAlgorithm>sha256</FileDigestAlgorithm>
</DriverSign>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\BDD.cxx" />
<ClCompile Include="..\BDD_DDI.cxx" />
<ClCompile Include="..\BDD_DMM.cxx" />
<ClCompile Include="..\BDD_Util.cxx" />
<ClCompile Include="..\BltFuncs.cxx" />
<ClCompile Include="..\BltHw.cxx" />
<ClCompile Include="..\memory.cxx" />
<ResourceCompile Include="..\sampledisplay.rc" />
</ItemGroup>
<ItemGroup>
<Inf Exclude="@(Inf)" Include="*.inf" />
<FilesToPackage Include="$(TargetPath)" Condition="'$(ConfigurationType)'=='Driver' or '$(ConfigurationType)'=='DynamicLibrary'" />
</ItemGroup>
<ItemGroup>
<None Exclude="@(None)" Include="*.txt;*.htm;*.html" />
<None Exclude="@(None)" Include="*.ico;*.cur;*.bmp;*.dlg;*.rct;*.gif;*.jpg;*.jpeg;*.wav;*.jpe;*.tiff;*.tif;*.png;*.rc2" />
<None Exclude="@(None)" Include="*.def;*.bat;*.hpj;*.asmx" />
</ItemGroup>
<ItemGroup>
<ClInclude Exclude="@(ClInclude)" Include="*.h;*.hpp;*.hxx;*.hm;*.inl;*.xsd" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
</Project>
@@ -0,0 +1,49 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx;*</Extensions>
<UniqueIdentifier>{8B6C0A00-F837-4D16-A67B-98E6936A2729}</UniqueIdentifier>
</Filter>
<Filter Include="Header Files">
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
<UniqueIdentifier>{0D809CEB-9E9B-4357-B44D-BCDCA1D0A4A5}</UniqueIdentifier>
</Filter>
<Filter Include="Resource Files">
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms;man;xml</Extensions>
<UniqueIdentifier>{E61D9490-5CC2-4F32-AC2B-BCE3922E65F7}</UniqueIdentifier>
</Filter>
<Filter Include="Driver Files">
<Extensions>inf;inv;inx;mof;mc;</Extensions>
<UniqueIdentifier>{5A656697-E252-49C1-BF4E-B06BA46DF394}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\BDD.cxx">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\BDD_DDI.cxx">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\BDD_DMM.cxx">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\BDD_Util.cxx">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\BltFuncs.cxx">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\BltHw.cxx">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\memory.cxx">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="..\sampledisplay.rc">
<Filter>Resource Files</Filter>
</ResourceCompile>
</ItemGroup>
</Project>
Binary file not shown.
+854
View File
@@ -0,0 +1,854 @@
/******************************Module*Header*******************************\
* Module Name: bdd.cxx
*
* Basic Display Driver functions implementation
*
*
* Copyright (c) 2010 Microsoft Corporation
\**************************************************************************/
#include "BDD.hxx"
#pragma code_seg("PAGE")
BASIC_DISPLAY_DRIVER::BASIC_DISPLAY_DRIVER(_In_ DEVICE_OBJECT* pPhysicalDeviceObject) : m_pPhysicalDevice(pPhysicalDeviceObject),
m_MonitorPowerState(PowerDeviceD0),
m_AdapterPowerState(PowerDeviceD0)
{
PAGED_CODE();
*((UINT*)&m_Flags) = 0;
m_Flags._LastFlag = TRUE;
RtlZeroMemory(&m_DxgkInterface, sizeof(m_DxgkInterface));
RtlZeroMemory(&m_StartInfo, sizeof(m_StartInfo));
RtlZeroMemory(m_CurrentModes, sizeof(m_CurrentModes));
RtlZeroMemory(&m_DeviceInfo, sizeof(m_DeviceInfo));
for (UINT i=0;i<MAX_VIEWS;i++)
{
m_HardwareBlt[i].Initialize(this,i);
}
}
BASIC_DISPLAY_DRIVER::~BASIC_DISPLAY_DRIVER()
{
PAGED_CODE();
CleanUp();
}
NTSTATUS BASIC_DISPLAY_DRIVER::StartDevice(_In_ DXGK_START_INFO* pDxgkStartInfo,
_In_ DXGKRNL_INTERFACE* pDxgkInterface,
_Out_ ULONG* pNumberOfViews,
_Out_ ULONG* pNumberOfChildren)
{
PAGED_CODE();
BDD_ASSERT(pDxgkStartInfo != NULL);
BDD_ASSERT(pDxgkInterface != NULL);
BDD_ASSERT(pNumberOfViews != NULL);
BDD_ASSERT(pNumberOfChildren != NULL);
RtlCopyMemory(&m_StartInfo, pDxgkStartInfo, sizeof(m_StartInfo));
RtlCopyMemory(&m_DxgkInterface, pDxgkInterface, sizeof(m_DxgkInterface));
RtlZeroMemory(m_CurrentModes, sizeof(m_CurrentModes));
m_CurrentModes[0].DispInfo.TargetId = D3DDDI_ID_UNINITIALIZED;
// Get device information from OS.
NTSTATUS Status = m_DxgkInterface.DxgkCbGetDeviceInformation(m_DxgkInterface.DeviceHandle, &m_DeviceInfo);
if (!NT_SUCCESS(Status))
{
BDD_LOG_ASSERTION1("DxgkCbGetDeviceInformation failed with status 0x%I64x",
Status);
return Status;
}
// Ignore return value, since it's not the end of the world if we failed to write these values to the registry
RegisterHWInfo();
// TODO: Uncomment the line below after updating the TODOs in the function CheckHardware
// Status = CheckHardware();
if (!NT_SUCCESS(Status))
{
return Status;
}
// This sample driver only uses the frame buffer of the POST device. DxgkCbAcquirePostDisplayOwnership
// gives you the frame buffer address and ensures that no one else is drawing to it. Be sure to give it back!
Status = m_DxgkInterface.DxgkCbAcquirePostDisplayOwnership(m_DxgkInterface.DeviceHandle, &(m_CurrentModes[0].DispInfo));
if (!NT_SUCCESS(Status) || m_CurrentModes[0].DispInfo.Width == 0)
{
// The most likely cause of failure is that the driver is simply not running on a POST device, or we are running
// after a pre-WDDM 1.2 driver. Since we can't draw anything, we should fail to start.
return STATUS_UNSUCCESSFUL;
}
m_Flags.DriverStarted = TRUE;
*pNumberOfViews = MAX_VIEWS;
*pNumberOfChildren = MAX_CHILDREN;
return STATUS_SUCCESS;
}
NTSTATUS BASIC_DISPLAY_DRIVER::StopDevice(VOID)
{
PAGED_CODE();
CleanUp();
m_Flags.DriverStarted = FALSE;
return STATUS_SUCCESS;
}
VOID BASIC_DISPLAY_DRIVER::CleanUp()
{
PAGED_CODE();
for (UINT Source = 0; Source < MAX_VIEWS; ++Source)
{
if (m_CurrentModes[Source].FrameBuffer.Ptr)
{
UnmapFrameBuffer(m_CurrentModes[Source].FrameBuffer.Ptr, m_CurrentModes[Source].DispInfo.Height * m_CurrentModes[Source].DispInfo.Pitch);
m_CurrentModes[Source].FrameBuffer.Ptr = NULL;
m_CurrentModes[Source].Flags.FrameBufferIsActive = FALSE;
}
}
}
NTSTATUS BASIC_DISPLAY_DRIVER::DispatchIoRequest(_In_ ULONG VidPnSourceId,
_In_ VIDEO_REQUEST_PACKET* pVideoRequestPacket)
{
PAGED_CODE();
BDD_ASSERT(pVideoRequestPacket != NULL);
BDD_ASSERT(VidPnSourceId < MAX_VIEWS);
return STATUS_NOT_IMPLEMENTED;
}
NTSTATUS BASIC_DISPLAY_DRIVER::SetPowerState(_In_ ULONG HardwareUid,
_In_ DEVICE_POWER_STATE DevicePowerState,
_In_ POWER_ACTION ActionType)
{
PAGED_CODE();
UNREFERENCED_PARAMETER(ActionType);
BDD_ASSERT((HardwareUid < MAX_CHILDREN) || (HardwareUid == DISPLAY_ADAPTER_HW_ID));
if (HardwareUid == DISPLAY_ADAPTER_HW_ID)
{
if (DevicePowerState == PowerDeviceD0)
{
// When returning from D3 the device visibility defined to be off for all targets
if (m_AdapterPowerState == PowerDeviceD3)
{
DXGKARG_SETVIDPNSOURCEVISIBILITY Visibility;
Visibility.VidPnSourceId = D3DDDI_ID_ALL;
Visibility.Visible = FALSE;
SetVidPnSourceVisibility(&Visibility);
}
}
// Store new adapter power state
m_AdapterPowerState = DevicePowerState;
// There is nothing to do to specifically power up/down the display adapter
return STATUS_SUCCESS;
}
else
{
// TODO: This is where the specified monitor should be powered up/down
NOTHING;
return STATUS_SUCCESS;
}
}
NTSTATUS BASIC_DISPLAY_DRIVER::QueryChildRelations(_Out_writes_bytes_(ChildRelationsSize) DXGK_CHILD_DESCRIPTOR* pChildRelations,
_In_ ULONG ChildRelationsSize)
{
PAGED_CODE();
BDD_ASSERT(pChildRelations != NULL);
// The last DXGK_CHILD_DESCRIPTOR in the array of pChildRelations must remain zeroed out, so we subtract this from the count
ULONG ChildRelationsCount = (ChildRelationsSize / sizeof(DXGK_CHILD_DESCRIPTOR)) - 1;
BDD_ASSERT(ChildRelationsCount <= MAX_CHILDREN);
for (UINT ChildIndex = 0; ChildIndex < ChildRelationsCount; ++ChildIndex)
{
pChildRelations[ChildIndex].ChildDeviceType = TypeVideoOutput;
pChildRelations[ChildIndex].ChildCapabilities.HpdAwareness = HpdAwarenessInterruptible;
pChildRelations[ChildIndex].ChildCapabilities.Type.VideoOutput.InterfaceTechnology = m_CurrentModes[0].Flags.IsInternal ? D3DKMDT_VOT_INTERNAL : D3DKMDT_VOT_OTHER;
pChildRelations[ChildIndex].ChildCapabilities.Type.VideoOutput.MonitorOrientationAwareness = D3DKMDT_MOA_NONE;
pChildRelations[ChildIndex].ChildCapabilities.Type.VideoOutput.SupportsSdtvModes = FALSE;
// TODO: Replace 0 with the actual ACPI ID of the child device, if available
pChildRelations[ChildIndex].AcpiUid = 0;
pChildRelations[ChildIndex].ChildUid = ChildIndex;
}
return STATUS_SUCCESS;
}
NTSTATUS BASIC_DISPLAY_DRIVER::QueryChildStatus(_Inout_ DXGK_CHILD_STATUS* pChildStatus,
_In_ BOOLEAN NonDestructiveOnly)
{
PAGED_CODE();
UNREFERENCED_PARAMETER(NonDestructiveOnly);
BDD_ASSERT(pChildStatus != NULL);
BDD_ASSERT(pChildStatus->ChildUid < MAX_CHILDREN);
switch (pChildStatus->Type)
{
case StatusConnection:
{
// HpdAwarenessInterruptible was reported since HpdAwarenessNone is deprecated.
// However, BDD has no knowledge of HotPlug events, so just always return connected.
pChildStatus->HotPlug.Connected = IsDriverActive();
return STATUS_SUCCESS;
}
case StatusRotation:
{
// D3DKMDT_MOA_NONE was reported, so this should never be called
BDD_LOG_ERROR0("Child status being queried for StatusRotation even though D3DKMDT_MOA_NONE was reported");
return STATUS_INVALID_PARAMETER;
}
default:
{
BDD_LOG_WARNING1("Unknown pChildStatus->Type (0x%I64x) requested.", pChildStatus->Type);
return STATUS_NOT_SUPPORTED;
}
}
}
// EDID retrieval
NTSTATUS BASIC_DISPLAY_DRIVER::QueryDeviceDescriptor(_In_ ULONG ChildUid,
_Inout_ DXGK_DEVICE_DESCRIPTOR* pDeviceDescriptor)
{
PAGED_CODE();
BDD_ASSERT(pDeviceDescriptor != NULL);
BDD_ASSERT(ChildUid < MAX_CHILDREN);
// If we haven't successfully retrieved an EDID yet (invalid ones are ok, so long as it was retrieved)
if (!m_Flags.EDID_Attempted)
{
GetEdid(ChildUid);
}
if (!m_Flags.EDID_Retrieved || !m_Flags.EDID_ValidHeader || !m_Flags.EDID_ValidChecksum)
{
// Report no EDID if a valid one wasn't retrieved
return STATUS_GRAPHICS_CHILD_DESCRIPTOR_NOT_SUPPORTED;
}
else if (pDeviceDescriptor->DescriptorOffset == 0)
{
// Only the base block is supported
RtlCopyMemory(pDeviceDescriptor->DescriptorBuffer,
m_EDIDs[ChildUid],
min(pDeviceDescriptor->DescriptorLength, EDID_V1_BLOCK_SIZE));
return STATUS_SUCCESS;
}
else
{
return STATUS_MONITOR_NO_MORE_DESCRIPTOR_DATA;
}
}
NTSTATUS BASIC_DISPLAY_DRIVER::QueryAdapterInfo(_In_ CONST DXGKARG_QUERYADAPTERINFO* pQueryAdapterInfo)
{
PAGED_CODE();
BDD_ASSERT(pQueryAdapterInfo != NULL);
switch (pQueryAdapterInfo->Type)
{
case DXGKQAITYPE_DRIVERCAPS:
{
if (pQueryAdapterInfo->OutputDataSize < sizeof(DXGK_DRIVERCAPS))
{
BDD_LOG_ERROR2("pQueryAdapterInfo->OutputDataSize (0x%I64x) is smaller than sizeof(DXGK_DRIVERCAPS) (0x%I64x)", pQueryAdapterInfo->OutputDataSize, sizeof(DXGK_DRIVERCAPS));
return STATUS_BUFFER_TOO_SMALL;
}
DXGK_DRIVERCAPS* pDriverCaps = (DXGK_DRIVERCAPS*)pQueryAdapterInfo->pOutputData;
// Nearly all fields must be initialized to zero, so zero out to start and then change those that are non-zero.
// Fields are zero since BDD is Display-Only and therefore does not support any of the render related fields.
// It also doesn't support hardware interrupts, gamma ramps, etc.
RtlZeroMemory(pDriverCaps, sizeof(DXGK_DRIVERCAPS));
pDriverCaps->WDDMVersion = DXGKDDI_WDDMv1_2;
pDriverCaps->HighestAcceptableAddress.QuadPart = -1;
pDriverCaps->SupportNonVGA = TRUE;
pDriverCaps->SupportSmoothRotation = TRUE;
return STATUS_SUCCESS;
}
case DXGKQAITYPE_DISPLAY_DRIVERCAPS_EXTENSION:
{
DXGK_DISPLAY_DRIVERCAPS_EXTENSION* pDriverDisplayCaps;
if (pQueryAdapterInfo->OutputDataSize < sizeof(*pDriverDisplayCaps))
{
BDD_LOG_ERROR2("pQueryAdapterInfo->OutputDataSize (0x%I64x) is smaller than sizeof(DXGK_DISPLAY_DRIVERCAPS_EXTENSION) (0x%I64x)",
pQueryAdapterInfo->OutputDataSize,
sizeof(DXGK_DISPLAY_DRIVERCAPS_EXTENSION));
return STATUS_INVALID_PARAMETER;
}
pDriverDisplayCaps = (DXGK_DISPLAY_DRIVERCAPS_EXTENSION*)pQueryAdapterInfo->pOutputData;
// Reset all caps values
RtlZeroMemory(pDriverDisplayCaps, pQueryAdapterInfo->OutputDataSize);
// We claim to support virtual display mode.
pDriverDisplayCaps->VirtualModeSupport = 1;
return STATUS_SUCCESS;
}
default:
{
// BDD does not need to support any other adapter information types
BDD_LOG_WARNING1("Unknown QueryAdapterInfo Type (0x%I64x) requested", pQueryAdapterInfo->Type);
return STATUS_NOT_SUPPORTED;
}
}
}
NTSTATUS BASIC_DISPLAY_DRIVER::CheckHardware()
{
PAGED_CODE();
NTSTATUS Status;
ULONG VendorID;
ULONG DeviceID;
// TODO: If developing a driver for PCI based hardware, then use the second method to retrieve Vendor/Device IDs.
// If developing for non-PCI based hardware (i.e. ACPI based hardware), use the first method to retrieve the IDs.
#if 1 // ACPI-based device
// Get the Vendor & Device IDs on non-PCI system
ACPI_EVAL_INPUT_BUFFER_COMPLEX AcpiInputBuffer = {0};
AcpiInputBuffer.Signature = ACPI_EVAL_INPUT_BUFFER_COMPLEX_SIGNATURE;
AcpiInputBuffer.MethodNameAsUlong = ACPI_METHOD_HARDWARE_ID;
AcpiInputBuffer.Size = 0;
AcpiInputBuffer.ArgumentCount = 0;
BYTE OutputBuffer[sizeof(ACPI_EVAL_OUTPUT_BUFFER) + 0x10];
RtlZeroMemory(OutputBuffer, sizeof(OutputBuffer));
ACPI_EVAL_OUTPUT_BUFFER* pAcpiOutputBuffer = reinterpret_cast<ACPI_EVAL_OUTPUT_BUFFER*>(&OutputBuffer);
Status = m_DxgkInterface.DxgkCbEvalAcpiMethod(m_DxgkInterface.DeviceHandle,
DISPLAY_ADAPTER_HW_ID,
&AcpiInputBuffer,
sizeof(AcpiInputBuffer),
pAcpiOutputBuffer,
sizeof(OutputBuffer));
if (!NT_SUCCESS(Status))
{
BDD_LOG_ERROR1("DxgkCbReadDeviceSpace failed to get hardware IDs with status 0x%I64x", Status);
return Status;
}
VendorID = ((ULONG*)(pAcpiOutputBuffer->Argument[0].Data))[0];
DeviceID = ((ULONG*)(pAcpiOutputBuffer->Argument[0].Data))[1];
#else // PCI-based device
// Get the Vendor & Device IDs on PCI system
PCI_COMMON_HEADER Header = {0};
ULONG BytesRead;
Status = m_DxgkInterface.DxgkCbReadDeviceSpace(m_DxgkInterface.DeviceHandle,
DXGK_WHICHSPACE_CONFIG,
&Header,
0,
sizeof(Header),
&BytesRead);
if (!NT_SUCCESS(Status))
{
BDD_LOG_ERROR1("DxgkCbReadDeviceSpace failed with status 0x%I64x", Status);
return Status;
}
VendorID = Header.VendorID;
DeviceID = Header.DeviceID;
#endif
// TODO: Replace 0x1414 with your Vendor ID
if (VendorID == 0x1414)
{
switch (DeviceID)
{
// TODO: Replace the case statements below with the Device IDs supported by this driver
case 0x0000:
case 0xFFFF: return STATUS_SUCCESS;
}
}
return STATUS_GRAPHICS_DRIVER_MISMATCH;
}
// Even though Sample Basic Display Driver does not support hardware cursors, and reports such
// in QueryAdapterInfo. This function can still be called to set the pointer to not visible
NTSTATUS BASIC_DISPLAY_DRIVER::SetPointerPosition(_In_ CONST DXGKARG_SETPOINTERPOSITION* pSetPointerPosition)
{
PAGED_CODE();
BDD_ASSERT(pSetPointerPosition != NULL);
BDD_ASSERT(pSetPointerPosition->VidPnSourceId < MAX_VIEWS);
if (!(pSetPointerPosition->Flags.Visible))
{
return STATUS_SUCCESS;
}
else
{
BDD_LOG_ASSERTION0("SetPointerPosition should never be called to set the pointer to visible since BDD doesn't support hardware cursors.");
return STATUS_UNSUCCESSFUL;
}
}
// Basic Sample Display Driver does not support hardware cursors, and reports such
// in QueryAdapterInfo. Therefore this function should never be called.
NTSTATUS BASIC_DISPLAY_DRIVER::SetPointerShape(_In_ CONST DXGKARG_SETPOINTERSHAPE* pSetPointerShape)
{
PAGED_CODE();
BDD_ASSERT(pSetPointerShape != NULL);
BDD_LOG_ASSERTION0("SetPointerShape should never be called since BDD doesn't support hardware cursors.");
return STATUS_NOT_IMPLEMENTED;
}
NTSTATUS BASIC_DISPLAY_DRIVER::PresentDisplayOnly(_In_ CONST DXGKARG_PRESENT_DISPLAYONLY* pPresentDisplayOnly)
{
PAGED_CODE();
BDD_ASSERT(pPresentDisplayOnly != NULL);
BDD_ASSERT(pPresentDisplayOnly->VidPnSourceId < MAX_VIEWS);
if (pPresentDisplayOnly->BytesPerPixel < MIN_BYTES_PER_PIXEL_REPORTED)
{
// Only >=32bpp modes are reported, therefore this Present should never pass anything less than 4 bytes per pixel
BDD_LOG_ERROR1("pPresentDisplayOnly->BytesPerPixel is 0x%I64x, which is lower than the allowed.", pPresentDisplayOnly->BytesPerPixel);
return STATUS_INVALID_PARAMETER;
}
// If it is in monitor off state or source is not supposed to be visible, don't present anything to the screen
if ((m_MonitorPowerState > PowerDeviceD0) ||
(m_CurrentModes[pPresentDisplayOnly->VidPnSourceId].Flags.SourceNotVisible))
{
return STATUS_SUCCESS;
}
// Present is only valid if the target is actively connected to this source
if (m_CurrentModes[pPresentDisplayOnly->VidPnSourceId].Flags.FrameBufferIsActive)
{
// If actual pixels are coming through, will need to completely zero out physical address next time in BlackOutScreen
m_CurrentModes[pPresentDisplayOnly->VidPnSourceId].ZeroedOutStart.QuadPart = 0;
m_CurrentModes[pPresentDisplayOnly->VidPnSourceId].ZeroedOutEnd.QuadPart = 0;
D3DKMDT_VIDPN_PRESENT_PATH_ROTATION RotationNeededByFb = pPresentDisplayOnly->Flags.Rotate ?
m_CurrentModes[pPresentDisplayOnly->VidPnSourceId].Rotation :
D3DKMDT_VPPR_IDENTITY;
BYTE* pDst = (BYTE*)m_CurrentModes[pPresentDisplayOnly->VidPnSourceId].FrameBuffer.Ptr;
UINT DstBitPerPixel = BPPFromPixelFormat(m_CurrentModes[pPresentDisplayOnly->VidPnSourceId].DispInfo.ColorFormat);
if (m_CurrentModes[pPresentDisplayOnly->VidPnSourceId].Scaling == D3DKMDT_VPPS_CENTERED)
{
UINT CenterShift = (m_CurrentModes[pPresentDisplayOnly->VidPnSourceId].DispInfo.Height -
m_CurrentModes[pPresentDisplayOnly->VidPnSourceId].SrcModeHeight)*m_CurrentModes[pPresentDisplayOnly->VidPnSourceId].DispInfo.Pitch;
CenterShift += (m_CurrentModes[pPresentDisplayOnly->VidPnSourceId].DispInfo.Width -
m_CurrentModes[pPresentDisplayOnly->VidPnSourceId].SrcModeWidth)*DstBitPerPixel/8;
pDst += (int)CenterShift/2;
}
return m_HardwareBlt[pPresentDisplayOnly->VidPnSourceId].ExecutePresentDisplayOnly(pDst,
DstBitPerPixel,
(BYTE*)pPresentDisplayOnly->pSource,
pPresentDisplayOnly->BytesPerPixel,
pPresentDisplayOnly->Pitch,
pPresentDisplayOnly->NumMoves,
pPresentDisplayOnly->pMoves,
pPresentDisplayOnly->NumDirtyRects,
pPresentDisplayOnly->pDirtyRect,
RotationNeededByFb);
}
return STATUS_SUCCESS;
}
NTSTATUS BASIC_DISPLAY_DRIVER::StopDeviceAndReleasePostDisplayOwnership(_In_ D3DDDI_VIDEO_PRESENT_TARGET_ID TargetId,
_Out_ DXGK_DISPLAY_INFORMATION* pDisplayInfo)
{
PAGED_CODE();
BDD_ASSERT(TargetId < MAX_CHILDREN);
D3DDDI_VIDEO_PRESENT_SOURCE_ID SourceId = FindSourceForTarget(TargetId, TRUE);
// In case BDD is the next driver to run, the monitor should not be off, since
// this could cause the BIOS to hang when the EDID is retrieved on Start.
if (m_MonitorPowerState > PowerDeviceD0)
{
SetPowerState(TargetId, PowerDeviceD0, PowerActionNone);
}
// The driver has to black out the display and ensure it is visible when releasing ownership
BlackOutScreen(SourceId);
*pDisplayInfo = m_CurrentModes[SourceId].DispInfo;
return StopDevice();
}
NTSTATUS BASIC_DISPLAY_DRIVER::QueryVidPnHWCapability(_Inout_ DXGKARG_QUERYVIDPNHWCAPABILITY* pVidPnHWCaps)
{
PAGED_CODE();
BDD_ASSERT(pVidPnHWCaps != NULL);
BDD_ASSERT(pVidPnHWCaps->SourceId < MAX_VIEWS);
BDD_ASSERT(pVidPnHWCaps->TargetId < MAX_CHILDREN);
pVidPnHWCaps->VidPnHWCaps.DriverRotation = 1; // BDD does rotation in software
pVidPnHWCaps->VidPnHWCaps.DriverScaling = 0; // BDD does not support scaling
pVidPnHWCaps->VidPnHWCaps.DriverCloning = 0; // BDD does not support clone
pVidPnHWCaps->VidPnHWCaps.DriverColorConvert = 1; // BDD does color conversions in software
pVidPnHWCaps->VidPnHWCaps.DriverLinkedAdapaterOutput = 0; // BDD does not support linked adapters
pVidPnHWCaps->VidPnHWCaps.DriverRemoteDisplay = 0; // BDD does not support remote displays
return STATUS_SUCCESS;
}
NTSTATUS BASIC_DISPLAY_DRIVER::GetEdid(D3DDDI_VIDEO_PRESENT_TARGET_ID TargetId)
{
PAGED_CODE();
BDD_ASSERT_CHK(!m_Flags.EDID_Attempted);
NTSTATUS Status = STATUS_SUCCESS;
RtlZeroMemory(m_EDIDs[TargetId], sizeof(m_EDIDs[TargetId]));
m_Flags.EDID_Attempted = TRUE;
return Status;
}
VOID BASIC_DISPLAY_DRIVER::BlackOutScreen(D3DDDI_VIDEO_PRESENT_SOURCE_ID SourceId)
{
PAGED_CODE();
UINT ScreenHeight = m_CurrentModes[SourceId].DispInfo.Height;
UINT ScreenPitch = m_CurrentModes[SourceId].DispInfo.Pitch;
PHYSICAL_ADDRESS NewPhysAddrStart = m_CurrentModes[SourceId].DispInfo.PhysicAddress;
PHYSICAL_ADDRESS NewPhysAddrEnd;
NewPhysAddrEnd.QuadPart = NewPhysAddrStart.QuadPart + (ScreenHeight * ScreenPitch);
if (m_CurrentModes[SourceId].Flags.FrameBufferIsActive)
{
BYTE* MappedAddr = reinterpret_cast<BYTE*>(m_CurrentModes[SourceId].FrameBuffer.Ptr);
// Zero any memory at the start that hasn't been zeroed recently
if (NewPhysAddrStart.QuadPart < m_CurrentModes[SourceId].ZeroedOutStart.QuadPart)
{
if (NewPhysAddrEnd.QuadPart < m_CurrentModes[SourceId].ZeroedOutStart.QuadPart)
{
// No overlap
RtlZeroMemory(MappedAddr, ScreenHeight * ScreenPitch);
}
else
{
RtlZeroMemory(MappedAddr, (UINT)(m_CurrentModes[SourceId].ZeroedOutStart.QuadPart - NewPhysAddrStart.QuadPart));
}
}
// Zero any memory at the end that hasn't been zeroed recently
if (NewPhysAddrEnd.QuadPart > m_CurrentModes[SourceId].ZeroedOutEnd.QuadPart)
{
if (NewPhysAddrStart.QuadPart > m_CurrentModes[SourceId].ZeroedOutEnd.QuadPart)
{
// No overlap
// NOTE: When actual pixels were the most recent thing drawn, ZeroedOutStart & ZeroedOutEnd will both be 0
// and this is the path that will be used to black out the current screen.
RtlZeroMemory(MappedAddr, ScreenHeight * ScreenPitch);
}
else
{
RtlZeroMemory(MappedAddr, (UINT)(NewPhysAddrEnd.QuadPart - m_CurrentModes[SourceId].ZeroedOutEnd.QuadPart));
}
}
}
m_CurrentModes[SourceId].ZeroedOutStart.QuadPart = NewPhysAddrStart.QuadPart;
m_CurrentModes[SourceId].ZeroedOutEnd.QuadPart = NewPhysAddrEnd.QuadPart;
}
NTSTATUS BASIC_DISPLAY_DRIVER::WriteHWInfoStr(_In_ HANDLE DevInstRegKeyHandle, _In_ PCWSTR pszwValueName, _In_ PCSTR pszValue)
{
PAGED_CODE();
NTSTATUS Status;
ANSI_STRING AnsiStrValue;
UNICODE_STRING UnicodeStrValue;
UNICODE_STRING UnicodeStrValueName;
// ZwSetValueKey wants the ValueName as a UNICODE_STRING
RtlInitUnicodeString(&UnicodeStrValueName, pszwValueName);
// REG_SZ is for WCHARs, there is no equivalent for CHARs
// Use the ansi/unicode conversion functions to get from PSTR to PWSTR
RtlInitAnsiString(&AnsiStrValue, pszValue);
Status = RtlAnsiStringToUnicodeString(&UnicodeStrValue, &AnsiStrValue, TRUE);
if (!NT_SUCCESS(Status))
{
BDD_LOG_ERROR1("RtlAnsiStringToUnicodeString failed with Status: 0x%I64x", Status);
return Status;
}
// Write the value to the registry
Status = ZwSetValueKey(DevInstRegKeyHandle,
&UnicodeStrValueName,
0,
REG_SZ,
UnicodeStrValue.Buffer,
UnicodeStrValue.MaximumLength);
// Free the earlier allocated unicode string
RtlFreeUnicodeString(&UnicodeStrValue);
if (!NT_SUCCESS(Status))
{
BDD_LOG_ERROR1("ZwSetValueKey failed with Status: 0x%I64x", Status);
}
return Status;
}
NTSTATUS BASIC_DISPLAY_DRIVER::RegisterHWInfo()
{
PAGED_CODE();
NTSTATUS Status;
// TODO: Replace these strings with proper information
PCSTR StrHWInfoChipType = "Replace with the chip name";
PCSTR StrHWInfoDacType = "Replace with the DAC name or identifier (ID)";
PCSTR StrHWInfoAdapterString = "Replace with the name of the adapter";
PCSTR StrHWInfoBiosString = "Replace with information about the BIOS";
HANDLE DevInstRegKeyHandle;
Status = IoOpenDeviceRegistryKey(m_pPhysicalDevice, PLUGPLAY_REGKEY_DRIVER, KEY_SET_VALUE, &DevInstRegKeyHandle);
if (!NT_SUCCESS(Status))
{
BDD_LOG_ERROR2("IoOpenDeviceRegistryKey failed for PDO: 0x%I64x, Status: 0x%I64x", m_pPhysicalDevice, Status);
return Status;
}
Status = WriteHWInfoStr(DevInstRegKeyHandle, L"HardwareInformation.ChipType", StrHWInfoChipType);
if (!NT_SUCCESS(Status))
{
return Status;
}
Status = WriteHWInfoStr(DevInstRegKeyHandle, L"HardwareInformation.DacType", StrHWInfoDacType);
if (!NT_SUCCESS(Status))
{
return Status;
}
Status = WriteHWInfoStr(DevInstRegKeyHandle, L"HardwareInformation.AdapterString", StrHWInfoAdapterString);
if (!NT_SUCCESS(Status))
{
return Status;
}
Status = WriteHWInfoStr(DevInstRegKeyHandle, L"HardwareInformation.BiosString", StrHWInfoBiosString);
if (!NT_SUCCESS(Status))
{
return Status;
}
// MemorySize is a ULONG, unlike the others which are all strings
UNICODE_STRING ValueNameMemorySize;
RtlInitUnicodeString(&ValueNameMemorySize, L"HardwareInformation.MemorySize");
DWORD MemorySize = 0; // BDD has no access to video memory
Status = ZwSetValueKey(DevInstRegKeyHandle,
&ValueNameMemorySize,
0,
REG_DWORD,
&MemorySize,
sizeof(MemorySize));
if (!NT_SUCCESS(Status))
{
BDD_LOG_ERROR1("ZwSetValueKey for MemorySize failed with Status: 0x%I64x", Status);
return Status;
}
return Status;
}
//
// Non-Paged Code
//
#pragma code_seg(push)
#pragma code_seg()
D3DDDI_VIDEO_PRESENT_SOURCE_ID BASIC_DISPLAY_DRIVER::FindSourceForTarget(D3DDDI_VIDEO_PRESENT_TARGET_ID TargetId, BOOLEAN DefaultToZero)
{
UNREFERENCED_PARAMETER(TargetId);
BDD_ASSERT_CHK(TargetId < MAX_CHILDREN);
for (UINT SourceId = 0; SourceId < MAX_VIEWS; ++SourceId)
{
if (m_CurrentModes[SourceId].FrameBuffer.Ptr != NULL)
{
return SourceId;
}
}
return DefaultToZero ? 0 : D3DDDI_ID_UNINITIALIZED;
}
VOID BASIC_DISPLAY_DRIVER::DpcRoutine(VOID)
{
m_DxgkInterface.DxgkCbNotifyDpc((HANDLE)m_DxgkInterface.DeviceHandle);
}
BOOLEAN BASIC_DISPLAY_DRIVER::InterruptRoutine(_In_ ULONG MessageNumber)
{
UNREFERENCED_PARAMETER(MessageNumber);
// BDD cannot handle interrupts
return FALSE;
}
VOID BASIC_DISPLAY_DRIVER::ResetDevice(VOID)
{
}
// Must be Non-Paged, as it sets up the display for a bugcheck
NTSTATUS BASIC_DISPLAY_DRIVER::SystemDisplayEnable(_In_ D3DDDI_VIDEO_PRESENT_TARGET_ID TargetId,
_In_ PDXGKARG_SYSTEM_DISPLAY_ENABLE_FLAGS Flags,
_Out_ UINT* pWidth,
_Out_ UINT* pHeight,
_Out_ D3DDDIFORMAT* pColorFormat)
{
UNREFERENCED_PARAMETER(Flags);
m_SystemDisplaySourceId = D3DDDI_ID_UNINITIALIZED;
BDD_ASSERT((TargetId < MAX_CHILDREN) || (TargetId == D3DDDI_ID_UNINITIALIZED));
// Find the frame buffer for displaying the bugcheck, if it was successfully mapped
if (TargetId == D3DDDI_ID_UNINITIALIZED)
{
for (UINT SourceIdx = 0; SourceIdx < MAX_VIEWS; ++SourceIdx)
{
if (m_CurrentModes[SourceIdx].FrameBuffer.Ptr != NULL)
{
m_SystemDisplaySourceId = SourceIdx;
break;
}
}
}
else
{
m_SystemDisplaySourceId = FindSourceForTarget(TargetId, FALSE);
}
if (m_SystemDisplaySourceId == D3DDDI_ID_UNINITIALIZED)
{
{
return STATUS_UNSUCCESSFUL;
}
}
if ((m_CurrentModes[m_SystemDisplaySourceId].Rotation == D3DKMDT_VPPR_ROTATE90) ||
(m_CurrentModes[m_SystemDisplaySourceId].Rotation == D3DKMDT_VPPR_ROTATE270))
{
*pHeight = m_CurrentModes[m_SystemDisplaySourceId].DispInfo.Width;
*pWidth = m_CurrentModes[m_SystemDisplaySourceId].DispInfo.Height;
}
else
{
*pWidth = m_CurrentModes[m_SystemDisplaySourceId].DispInfo.Width;
*pHeight = m_CurrentModes[m_SystemDisplaySourceId].DispInfo.Height;
}
*pColorFormat = m_CurrentModes[m_SystemDisplaySourceId].DispInfo.ColorFormat;
return STATUS_SUCCESS;
}
// Must be Non-Paged, as it is called to display the bugcheck screen
VOID BASIC_DISPLAY_DRIVER::SystemDisplayWrite(_In_reads_bytes_(SourceHeight * SourceStride) VOID* pSource,
_In_ UINT SourceWidth,
_In_ UINT SourceHeight,
_In_ UINT SourceStride,
_In_ INT PositionX,
_In_ INT PositionY)
{
// Rect will be Offset by PositionX/Y in the src to reset it back to 0
RECT Rect;
Rect.left = PositionX;
Rect.top = PositionY;
Rect.right = Rect.left + SourceWidth;
Rect.bottom = Rect.top + SourceHeight;
// Set up destination blt info
BLT_INFO DstBltInfo;
DstBltInfo.pBits = m_CurrentModes[m_SystemDisplaySourceId].FrameBuffer.Ptr;
DstBltInfo.Pitch = m_CurrentModes[m_SystemDisplaySourceId].DispInfo.Pitch;
DstBltInfo.BitsPerPel = BPPFromPixelFormat(m_CurrentModes[m_SystemDisplaySourceId].DispInfo.ColorFormat);
DstBltInfo.Offset.x = 0;
DstBltInfo.Offset.y = 0;
DstBltInfo.Rotation = m_CurrentModes[m_SystemDisplaySourceId].Rotation;
DstBltInfo.Width = m_CurrentModes[m_SystemDisplaySourceId].DispInfo.Width;
DstBltInfo.Height = m_CurrentModes[m_SystemDisplaySourceId].DispInfo.Height;
// Set up source blt info
BLT_INFO SrcBltInfo;
SrcBltInfo.pBits = pSource;
SrcBltInfo.Pitch = SourceStride;
SrcBltInfo.BitsPerPel = 32;
SrcBltInfo.Offset.x = -PositionX;
SrcBltInfo.Offset.y = -PositionY;
SrcBltInfo.Rotation = D3DKMDT_VPPR_IDENTITY;
SrcBltInfo.Width = SourceWidth;
SrcBltInfo.Height = SourceHeight;
BltBits(&DstBltInfo,
&SrcBltInfo,
1, // NumRects
&Rect);
}
#pragma code_seg(pop) // End Non-Paged Code
+650
View File
@@ -0,0 +1,650 @@
/******************************Module*Header*******************************\
* Module Name: BDD.hxx
*
* Basic Display Driver header file
*
*
* Copyright (c) 2010 Microsoft Corporation
\**************************************************************************/
#ifndef _BDD_HXX_
#define _BDD_HXX_
extern "C"
{
#define __CPLUSPLUS
// Standard C-runtime headers
#include <stddef.h>
#include <string.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <initguid.h>
// NTOS headers
#include <ntddk.h>
#ifndef FAR
#define FAR
#endif
// Windows headers
#include <windef.h>
#include <winerror.h>
// Windows GDI headers
#include <wingdi.h>
// Windows DDI headers
#include <winddi.h>
#include <ntddvdeo.h>
#include <d3dkmddi.h>
#include <d3dkmthk.h>
#include <ntstrsafe.h>
#include <ntintsafe.h>
#include <dispmprt.h>
};
#define EDID_V1_BLOCK_SIZE 128
#include "BDD_ErrorLog.hxx"
#define MIN_WIDTH 640
#define MIN_HEIGHT 480
#define MIN_BITS_PER_PIXEL_ALLOWED 8
#define MIN_BYTES_PER_PIXEL_REPORTED 4
#define DEFAULT_WIDTH 1024
#define DEFAULT_HEIGHT 768
#define MAX_INVALID_INHERITED_WIDTH 1024
#define MAX_INVALID_INHERITED_HEIGHT 768
#define BITS_PER_BYTE 8
typedef struct _BLT_INFO
{
PVOID pBits;
UINT Pitch;
UINT BitsPerPel;
POINT Offset; // To unrotated top-left of dirty rects
D3DKMDT_VIDPN_PRESENT_PATH_ROTATION Rotation;
UINT Width; // For the unrotated image
UINT Height; // For the unrotated image
} BLT_INFO;
#define MAX_CHILDREN 1
#define MAX_VIEWS 1
typedef struct _BDD_FLAGS
{
UINT DriverStarted : 1; // ( 1) 1 after StartDevice and 0 after StopDevice
UINT EDID_Retrieved : 1; // ( 2) EDID was successfully retrieved
UINT EDID_ValidChecksum : 1; // ( 3) Retrieved EDID has a valid checksum
UINT EDID_ValidHeader : 1; // ( 4) Retrieved EDID has a valid header
UINT EDID_Attempted : 1; // ( 5) 1 if an attempt was made to retrieve the EDID, successful or not
// IMPORTANT: All new flags must be added to just before _LastFlag (i.e. right above this comment), this allows different versions of diagnostics to still be useful.
UINT _LastFlag : 1; // ( 6) Always set to 1, is used to ensure that diagnostic version matches binary version
UINT Unused : 26;
} BDD_FLAGS;
// Represents the current mode, may not always be set (i.e. frame buffer mapped) if representing the mode passed in on single mode setups.
typedef struct _CURRENT_BDD_MODE
{
// The source mode currently set for HW Framebuffer
// For sample driver this info filled in StartDevice by the OS and never changed.
DXGK_DISPLAY_INFORMATION DispInfo;
// The rotation of the current mode. Rotation is performed in software during Present call
D3DKMDT_VIDPN_PRESENT_PATH_ROTATION Rotation;
D3DKMDT_VIDPN_PRESENT_PATH_SCALING Scaling;
// This mode might be different from one which are supported for HW frame buffer
// Scaling/displasment might be needed (if supported)
UINT SrcModeWidth;
UINT SrcModeHeight;
// Various boolean flags the struct uses
struct _CURRENT_BDD_MODE_FLAGS
{
UINT SourceNotVisible : 1; // 0 if source is visible
UINT FullscreenPresent : 1; // 0 if should use dirty rects for present
UINT FrameBufferIsActive : 1; // 0 if not currently active (i.e. target not connected to source)
UINT DoNotMapOrUnmap : 1; // 1 if the FrameBuffer should not be (un)mapped during normal execution
UINT IsInternal : 1; // 1 if it was determined (i.e. through ACPI) that an internal panel is being driven
UINT Unused : 27;
} Flags;
// The start and end of physical memory known to be all zeroes. Used to optimize the BlackOutScreen function to not write
// zeroes to memory already known to be zero. (Physical address is located in DispInfo)
PHYSICAL_ADDRESS ZeroedOutStart;
PHYSICAL_ADDRESS ZeroedOutEnd;
// Linear frame buffer pointer
// A union with a ULONG64 is used here to ensure this struct looks the same on 32bit and 64bit builds
// since the size of a VOID* changes depending on the build.
union
{
VOID* Ptr;
ULONG64 Force8Bytes;
} FrameBuffer;
} CURRENT_BDD_MODE;
class BASIC_DISPLAY_DRIVER;
class BDD_HWBLT
{
public:
D3DDDI_VIDEO_PRESENT_SOURCE_ID m_SourceId;
BASIC_DISPLAY_DRIVER* m_DevExt;
BOOLEAN m_SynchExecution;
HANDLE m_hPresentWorkerThread;
PVOID m_pPresentWorkerThread;
// Events to contol thread execution
KEVENT m_hThreadStartupEvent;
KEVENT m_hThreadSuspendEvent;
BDD_HWBLT();
~BDD_HWBLT();
void Initialize(_In_ BASIC_DISPLAY_DRIVER* DevExt, _In_ UINT IdSrc) { m_DevExt = DevExt; m_SourceId = IdSrc; }
void SetPresentWorkerThreadInfo(HANDLE hWorkerThread);
NTSTATUS ExecutePresentDisplayOnly(_In_ BYTE* DstAddr,
_In_ UINT DstBitPerPixel,
_In_ BYTE* SrcAddr,
_In_ UINT SrcBytesPerPixel,
_In_ LONG SrcPitch,
_In_ ULONG NumMoves,
_In_ D3DKMT_MOVE_RECT* pMoves,
_In_ ULONG NumDirtyRects,
_In_ RECT* pDirtyRect,
_In_ D3DKMDT_VIDPN_PRESENT_PATH_ROTATION Rotation);
};
class BASIC_DISPLAY_DRIVER
{
private:
DEVICE_OBJECT* m_pPhysicalDevice;
DXGKRNL_INTERFACE m_DxgkInterface;
// Information passed in by StartDevice DDI
DXGK_START_INFO m_StartInfo;
// Array of EDIDs, currently only supporting base block, hence EDID_V1_BLOCK_SIZE for size of each EDID
BYTE m_EDIDs[MAX_CHILDREN][EDID_V1_BLOCK_SIZE];
CURRENT_BDD_MODE m_CurrentModes[MAX_VIEWS];
BDD_HWBLT m_HardwareBlt[MAX_VIEWS];
// Current monitorpower state (this needs to be changed if MAX_CHILDREN != 1)
DEVICE_POWER_STATE m_MonitorPowerState;
// Current adapter power state
DEVICE_POWER_STATE m_AdapterPowerState;
// Source ID to be used by SystemDisplay functions
D3DDDI_VIDEO_PRESENT_SOURCE_ID m_SystemDisplaySourceId;
// Various boolean flags the class uses
BDD_FLAGS m_Flags;
// Device information
DXGK_DEVICE_INFO m_DeviceInfo;
public:
BASIC_DISPLAY_DRIVER(_In_ DEVICE_OBJECT* pPhysicalDeviceObject);
~BASIC_DISPLAY_DRIVER();
#pragma code_seg(push)
#pragma code_seg()
BOOLEAN IsDriverActive() const
{
return m_Flags.DriverStarted;
}
#pragma code_seg(pop)
NTSTATUS StartDevice(_In_ DXGK_START_INFO* pDxgkStartInfo,
_In_ DXGKRNL_INTERFACE* pDxgkInterface,
_Out_ ULONG* pNumberOfViews,
_Out_ ULONG* pNumberOfChildren);
NTSTATUS StopDevice(VOID);
// Must be Non-Paged
VOID ResetDevice(VOID);
const CURRENT_BDD_MODE* GetCurrentMode(UINT SourceId) const
{
return (SourceId < MAX_VIEWS)?&m_CurrentModes[SourceId]:NULL;
}
const DXGKRNL_INTERFACE* GetDxgkInterface() const { return &m_DxgkInterface;}
// Not implemented since no IOCTLs currently handled.
NTSTATUS DispatchIoRequest(_In_ ULONG VidPnSourceId,
_In_ VIDEO_REQUEST_PACKET* pVideoRequestPacket);
// Used to either turn off/on monitor (if possible), or mark that system is going into hibernate
NTSTATUS SetPowerState(_In_ ULONG HardwareUid,
_In_ DEVICE_POWER_STATE DevicePowerState,
_In_ POWER_ACTION ActionType);
// Report back child capabilities
NTSTATUS QueryChildRelations(_Out_writes_bytes_(ChildRelationsSize) DXGK_CHILD_DESCRIPTOR* pChildRelations,
_In_ ULONG ChildRelationsSize);
NTSTATUS QueryChildStatus(_Inout_ DXGK_CHILD_STATUS* pChildStatus,
_In_ BOOLEAN NonDestructiveOnly);
// Return EDID if previously retrieved
NTSTATUS QueryDeviceDescriptor(_In_ ULONG ChildUid,
_Inout_ DXGK_DEVICE_DESCRIPTOR* pDeviceDescriptor);
// Must be Non-Paged
// BDD doesn't have interrupts, so just returns false
BOOLEAN InterruptRoutine(_In_ ULONG MessageNumber);
VOID DpcRoutine(VOID);
// Return DriverCaps, doesn't support other queries though
NTSTATUS QueryAdapterInfo(_In_ CONST DXGKARG_QUERYADAPTERINFO* pQueryAdapterInfo);
NTSTATUS SetPointerPosition(_In_ CONST DXGKARG_SETPOINTERPOSITION* pSetPointerPosition);
NTSTATUS SetPointerShape(_In_ CONST DXGKARG_SETPOINTERSHAPE* pSetPointerShape);
NTSTATUS PresentDisplayOnly(_In_ CONST DXGKARG_PRESENT_DISPLAYONLY* pPresentDisplayOnly);
NTSTATUS IsSupportedVidPn(_Inout_ DXGKARG_ISSUPPORTEDVIDPN* pIsSupportedVidPn);
NTSTATUS RecommendFunctionalVidPn(_In_ CONST DXGKARG_RECOMMENDFUNCTIONALVIDPN* CONST pRecommendFunctionalVidPn);
NTSTATUS RecommendVidPnTopology(_In_ CONST DXGKARG_RECOMMENDVIDPNTOPOLOGY* CONST pRecommendVidPnTopology);
NTSTATUS RecommendMonitorModes(_In_ CONST DXGKARG_RECOMMENDMONITORMODES* CONST pRecommendMonitorModes);
NTSTATUS EnumVidPnCofuncModality(_In_ CONST DXGKARG_ENUMVIDPNCOFUNCMODALITY* CONST pEnumCofuncModality);
NTSTATUS SetVidPnSourceVisibility(_In_ CONST DXGKARG_SETVIDPNSOURCEVISIBILITY* pSetVidPnSourceVisibility);
NTSTATUS CommitVidPn(_In_ CONST DXGKARG_COMMITVIDPN* CONST pCommitVidPn);
NTSTATUS UpdateActiveVidPnPresentPath(_In_ CONST DXGKARG_UPDATEACTIVEVIDPNPRESENTPATH* CONST pUpdateActiveVidPnPresentPath);
NTSTATUS QueryVidPnHWCapability(_Inout_ DXGKARG_QUERYVIDPNHWCAPABILITY* pVidPnHWCaps);
// Part of PnPStop (PnP instance only), returns current mode information (which will be passed to fallback instance by dxgkrnl)
NTSTATUS StopDeviceAndReleasePostDisplayOwnership(_In_ D3DDDI_VIDEO_PRESENT_TARGET_ID TargetId,
_Out_ DXGK_DISPLAY_INFORMATION* pDisplayInfo);
// Must be Non-Paged
// Call to initialize as part of bugcheck
NTSTATUS SystemDisplayEnable(_In_ D3DDDI_VIDEO_PRESENT_TARGET_ID TargetId,
_In_ PDXGKARG_SYSTEM_DISPLAY_ENABLE_FLAGS Flags,
_Out_ UINT* pWidth,
_Out_ UINT* pHeight,
_Out_ D3DDDIFORMAT* pColorFormat);
// Must be Non-Paged
// Write out pixels as part of bugcheck
VOID SystemDisplayWrite(_In_reads_bytes_(SourceHeight * SourceStride) VOID* pSource,
_In_ UINT SourceWidth,
_In_ UINT SourceHeight,
_In_ UINT SourceStride,
_In_ INT PositionX,
_In_ INT PositionY);
private:
VOID CleanUp();
NTSTATUS CommonStart();
NTSTATUS GetEdid(D3DDDI_VIDEO_PRESENT_TARGET_ID TargetId);
// Given pixel format, give back the bits per pixel. Only supports pixel formats expected by BDD
// (i.e. the ones found below in PixelFormatFromBPP or that may come in from FallbackStart)
// This is because these two functions combine to allow BDD to store the bpp of a VBE mode in the
// ColorFormat field of a DispInfo
UINT BPPFromPixelFormat(D3DDDIFORMAT Format) const
{
switch (Format)
{
case D3DDDIFMT_UNKNOWN: return 0;
case D3DDDIFMT_P8: return 8;
case D3DDDIFMT_R5G6B5: return 16;
case D3DDDIFMT_R8G8B8: return 24;
case D3DDDIFMT_X8R8G8B8: // fall through
case D3DDDIFMT_A8R8G8B8: return 32;
default: BDD_LOG_ASSERTION1("Unknown D3DDDIFORMAT 0x%I64x", Format); return 0;
}
}
// Given bits per pixel, return the pixel format at the same bpp
D3DDDIFORMAT PixelFormatFromBPP(UINT BPP) const
{
switch (BPP)
{
case 8: return D3DDDIFMT_P8;
case 16: return D3DDDIFMT_R5G6B5;
case 24: return D3DDDIFMT_R8G8B8;
case 32: return D3DDDIFMT_X8R8G8B8;
default: BDD_LOG_ASSERTION1("A bit per pixel of 0x%I64x is not supported.", BPP); return D3DDDIFMT_UNKNOWN;
}
}
// These two functions make checks on the values of some of the fields of their respective structures to ensure
// that the specified fields are supported by BDD, i.e. gamma ramp must be D3DDDI_GAMMARAMP_DEFAULT
NTSTATUS IsVidPnPathFieldsValid(CONST D3DKMDT_VIDPN_PRESENT_PATH* pPath) const;
NTSTATUS IsVidPnSourceModeFieldsValid(CONST D3DKMDT_VIDPN_SOURCE_MODE* pSourceMode) const;
VOID BlackOutScreen(D3DDDI_VIDEO_PRESENT_SOURCE_ID SourceId);
// Returns the index into gBddBiosData.BddModes of the VBE mode that matches the given VidPnSourceMode.
// If such a mode cannot be found, returns a number outside of [0, gBddBiosData.CountBddModes)
UINT FindMatchingVBEMode(CONST D3DKMDT_VIDPN_SOURCE_MODE* pSourceMode) const;
// Must be Non-Paged
// Returns the SourceId that has TargetId as a valid frame buffer or D3DDDI_ID_UNINITIALIZED if no such SourceId exists
D3DDDI_VIDEO_PRESENT_SOURCE_ID FindSourceForTarget(D3DDDI_VIDEO_PRESENT_TARGET_ID TargetId, BOOLEAN DefaultToZero);
// Set the given source mode on the given path
NTSTATUS SetSourceModeAndPath(CONST D3DKMDT_VIDPN_SOURCE_MODE* pSourceMode,
CONST D3DKMDT_VIDPN_PRESENT_PATH* pPath);
// Add the current mode to the given monitor source mode set
NTSTATUS AddSingleMonitorMode(_In_ CONST DXGKARG_RECOMMENDMONITORMODES* CONST pRecommendMonitorModes);
// Add the current mode to the given VidPn source mode set
NTSTATUS AddSingleSourceMode(_In_ CONST DXGK_VIDPNSOURCEMODESET_INTERFACE* pVidPnSourceModeSetInterface,
D3DKMDT_HVIDPNSOURCEMODESET hVidPnSourceModeSet,
D3DDDI_VIDEO_PRESENT_SOURCE_ID SourceId);
// Add the current mode (or the matching to pinned source mode) to the give VidPn target mode set
NTSTATUS AddSingleTargetMode(_In_ CONST DXGK_VIDPNTARGETMODESET_INTERFACE* pVidPnTargetModeSetInterface,
D3DKMDT_HVIDPNTARGETMODESET hVidPnTargetModeSet,
_In_opt_ CONST D3DKMDT_VIDPN_SOURCE_MODE* pVidPnPinnedSourceModeInfo,
D3DDDI_VIDEO_PRESENT_SOURCE_ID SourceId);
// Check that the hardware the driver is running on is hardware it is capable of driving.
NTSTATUS CheckHardware();
// Helper function for RegisterHWInfo
NTSTATUS WriteHWInfoStr(_In_ HANDLE DevInstRegKeyHandle, _In_ PCWSTR pszwValueName, _In_ PCSTR pszValue);
// Set the information in the registry as described here: http://msdn.microsoft.com/en-us/library/windows/hardware/ff569240(v=vs.85).aspx
NTSTATUS RegisterHWInfo();
};
//
// Blt functions
//
// Must be Non-Paged
VOID BltBits(
BLT_INFO* pDst,
CONST BLT_INFO* pSrc,
UINT NumRects,
_In_reads_(NumRects) CONST RECT *pRects);
//
// Driver Entry point
//
extern "C"
DRIVER_INITIALIZE DriverEntry;
//
// PnP DDIs
//
VOID
BddDdiUnload(VOID);
// If uncommenting ENABLE_DXGK_SAL in the sources file, all the below function prototypes should be updated to use
// the function typedef's from the header files. Additionally, annotations on the function definitions can be removed
// as they are inherited from the prototype definition here. As an example the entire 4-line prototype for BddDdiAddDevice
// is replaced by the single commented line below:
// DXGKDDI_ADD_DEVICE BddDdiAddDevice;
NTSTATUS
BddDdiAddDevice(
_In_ DEVICE_OBJECT* pPhysicalDeviceObject,
_Outptr_ PVOID* ppDeviceContext);
NTSTATUS
BddDdiRemoveDevice(
_In_ VOID* pDeviceContext);
NTSTATUS
BddDdiStartDevice(
_In_ VOID* pDeviceContext,
_In_ DXGK_START_INFO* pDxgkStartInfo,
_In_ DXGKRNL_INTERFACE* pDxgkInterface,
_Out_ ULONG* pNumberOfViews,
_Out_ ULONG* pNumberOfChildren);
NTSTATUS
BddDdiStopDevice(
_In_ VOID* pDeviceContext);
VOID
BddDdiResetDevice(
_In_ VOID* pDeviceContext);
NTSTATUS
BddDdiDispatchIoRequest(
_In_ VOID* pDeviceContext,
_In_ ULONG VidPnSourceId,
_In_ VIDEO_REQUEST_PACKET* pVideoRequestPacket);
NTSTATUS
BddDdiSetPowerState(
_In_ VOID* pDeviceContext,
_In_ ULONG HardwareUid,
_In_ DEVICE_POWER_STATE DevicePowerState,
_In_ POWER_ACTION ActionType);
NTSTATUS
BddDdiQueryChildRelations(
_In_ VOID* pDeviceContext,
_Out_writes_bytes_(ChildRelationsSize) DXGK_CHILD_DESCRIPTOR* pChildRelations,
_In_ ULONG ChildRelationsSize);
NTSTATUS
BddDdiQueryChildStatus(
_In_ VOID* pDeviceContext,
_Inout_ DXGK_CHILD_STATUS* pChildStatus,
_In_ BOOLEAN NonDestructiveOnly);
NTSTATUS
BddDdiQueryDeviceDescriptor(
_In_ VOID* pDeviceContext,
_In_ ULONG ChildUid,
_Inout_ DXGK_DEVICE_DESCRIPTOR* pDeviceDescriptor);
// Must be Non-Paged
BOOLEAN
BddDdiInterruptRoutine(
_In_ VOID* pDeviceContext,
_In_ ULONG MessageNumber);
VOID
BddDdiDpcRoutine(
_In_ VOID* pDeviceContext);
//
// WDDM Display Only Driver DDIs
//
NTSTATUS
APIENTRY
BddDdiQueryAdapterInfo(
_In_ CONST HANDLE hAdapter,
_In_ CONST DXGKARG_QUERYADAPTERINFO* pQueryAdapterInfo);
NTSTATUS
APIENTRY
BddDdiSetPointerPosition(
_In_ CONST HANDLE hAdapter,
_In_ CONST DXGKARG_SETPOINTERPOSITION* pSetPointerPosition);
NTSTATUS
APIENTRY
BddDdiSetPointerShape(
_In_ CONST HANDLE hAdapter,
_In_ CONST DXGKARG_SETPOINTERSHAPE* pSetPointerShape);
NTSTATUS
APIENTRY
BddDdiPresentDisplayOnly(
_In_ CONST HANDLE hAdapter,
_In_ CONST DXGKARG_PRESENT_DISPLAYONLY* pPresentDisplayOnly);
NTSTATUS
APIENTRY
BddDdiIsSupportedVidPn(
_In_ CONST HANDLE hAdapter,
_Inout_ DXGKARG_ISSUPPORTEDVIDPN* pIsSupportedVidPn);
NTSTATUS
APIENTRY
BddDdiRecommendFunctionalVidPn(
_In_ CONST HANDLE hAdapter,
_In_ CONST DXGKARG_RECOMMENDFUNCTIONALVIDPN* CONST pRecommendFunctionalVidPn);
NTSTATUS
APIENTRY
BddDdiRecommendVidPnTopology(
_In_ CONST HANDLE hAdapter,
_In_ CONST DXGKARG_RECOMMENDVIDPNTOPOLOGY* CONST pRecommendVidPnTopology);
NTSTATUS
APIENTRY
BddDdiRecommendMonitorModes(
_In_ CONST HANDLE hAdapter,
_In_ CONST DXGKARG_RECOMMENDMONITORMODES* CONST pRecommendMonitorModes);
NTSTATUS
APIENTRY
BddDdiEnumVidPnCofuncModality(
_In_ CONST HANDLE hAdapter,
_In_ CONST DXGKARG_ENUMVIDPNCOFUNCMODALITY* CONST pEnumCofuncModality);
NTSTATUS
APIENTRY
BddDdiSetVidPnSourceVisibility(
_In_ CONST HANDLE hAdapter,
_In_ CONST DXGKARG_SETVIDPNSOURCEVISIBILITY* pSetVidPnSourceVisibility);
NTSTATUS
APIENTRY
BddDdiCommitVidPn(
_In_ CONST HANDLE hAdapter,
_In_ CONST DXGKARG_COMMITVIDPN* CONST pCommitVidPn);
NTSTATUS
APIENTRY
BddDdiUpdateActiveVidPnPresentPath(
_In_ CONST HANDLE hAdapter,
_In_ CONST DXGKARG_UPDATEACTIVEVIDPNPRESENTPATH* CONST pUpdateActiveVidPnPresentPath);
NTSTATUS
APIENTRY
BddDdiQueryVidPnHWCapability(
_In_ CONST HANDLE hAdapter,
_Inout_ DXGKARG_QUERYVIDPNHWCAPABILITY* pVidPnHWCaps);
NTSTATUS
APIENTRY
BddDdiStopDeviceAndReleasePostDisplayOwnership(
_In_ VOID* pDeviceContext,
_In_ D3DDDI_VIDEO_PRESENT_TARGET_ID TargetId,
_Out_ DXGK_DISPLAY_INFORMATION* DisplayInfo);
// Must be Non-Paged
NTSTATUS
APIENTRY
BddDdiSystemDisplayEnable(
_In_ VOID* pDeviceContext,
_In_ D3DDDI_VIDEO_PRESENT_TARGET_ID TargetId,
_In_ PDXGKARG_SYSTEM_DISPLAY_ENABLE_FLAGS Flags,
_Out_ UINT* Width,
_Out_ UINT* Height,
_Out_ D3DDDIFORMAT* ColorFormat);
// Must be Non-Paged
VOID
APIENTRY
BddDdiSystemDisplayWrite(
_In_ VOID* pDeviceContext,
_In_ VOID* Source,
_In_ UINT SourceWidth,
_In_ UINT SourceHeight,
_In_ UINT SourceStride,
_In_ UINT PositionX,
_In_ UINT PositionY);
//
// Frame buffer map/unmap
//
NTSTATUS
MapFrameBuffer(
_In_ PHYSICAL_ADDRESS PhysicalAddress,
_In_ ULONG Length,
_Outptr_result_bytebuffer_(Length) VOID** VirtualAddress);
NTSTATUS
UnmapFrameBuffer(
_In_reads_bytes_(Length) VOID* VirtualAddress,
_In_ ULONG Length);
BOOLEAN
IsEdidHeaderValid(_In_reads_bytes_(EDID_V1_BLOCK_SIZE) const BYTE* pEdid);
BOOLEAN
IsEdidChecksumValid(_In_reads_bytes_(EDID_V1_BLOCK_SIZE) const BYTE* pEdid);
//
// Memory handling
//
// Defaulting the value of PoolType means that any call to new Foo()
// will raise a compiler error for being ambiguous. This is to help keep
// any calls to allocate memory from accidentally NOT going through
// these functions.
_When_((PoolType & NonPagedPoolMustSucceed) != 0,
__drv_reportError("Must succeed pool allocations are forbidden. "
"Allocation failures cause a system crash"))
void* __cdecl operator new(size_t Size, POOL_TYPE PoolType = PagedPool);
_When_((PoolType & NonPagedPoolMustSucceed) != 0,
__drv_reportError("Must succeed pool allocations are forbidden. "
"Allocation failures cause a system crash"))
void* __cdecl operator new[](size_t Size, POOL_TYPE PoolType = PagedPool);
void __cdecl operator delete(void* pObject);
void __cdecl operator delete(void* pObject, size_t s);
void __cdecl operator delete[](void* pObject);
// Pool allocation tag for the Sample Display Driver. All allocations use this tag.
#define BDDTAG 'DDBS'
#endif // _BDD_HXX_
+579
View File
@@ -0,0 +1,579 @@
/******************************Module*Header*******************************\
* Module Name: BDD_DDI.cxx
*
* Basic Display Driver DDI entry points redirects
*
*
* Copyright (c) 2010 Microsoft Corporation
\**************************************************************************/
#include "BDD.hxx"
#pragma code_seg(push)
#pragma code_seg("INIT")
// BEGIN: Init Code
//
// Driver Entry point
//
extern "C"
NTSTATUS
DriverEntry(
_In_ DRIVER_OBJECT* pDriverObject,
_In_ UNICODE_STRING* pRegistryPath)
{
PAGED_CODE();
// Initialize DDI function pointers and dxgkrnl
KMDDOD_INITIALIZATION_DATA InitialData = {0};
InitialData.Version = DXGKDDI_INTERFACE_VERSION;
InitialData.DxgkDdiAddDevice = BddDdiAddDevice;
InitialData.DxgkDdiStartDevice = BddDdiStartDevice;
InitialData.DxgkDdiStopDevice = BddDdiStopDevice;
InitialData.DxgkDdiResetDevice = BddDdiResetDevice;
InitialData.DxgkDdiRemoveDevice = BddDdiRemoveDevice;
InitialData.DxgkDdiDispatchIoRequest = BddDdiDispatchIoRequest;
InitialData.DxgkDdiInterruptRoutine = BddDdiInterruptRoutine;
InitialData.DxgkDdiDpcRoutine = BddDdiDpcRoutine;
InitialData.DxgkDdiQueryChildRelations = BddDdiQueryChildRelations;
InitialData.DxgkDdiQueryChildStatus = BddDdiQueryChildStatus;
InitialData.DxgkDdiQueryDeviceDescriptor = BddDdiQueryDeviceDescriptor;
InitialData.DxgkDdiSetPowerState = BddDdiSetPowerState;
InitialData.DxgkDdiUnload = BddDdiUnload;
InitialData.DxgkDdiQueryAdapterInfo = BddDdiQueryAdapterInfo;
InitialData.DxgkDdiSetPointerPosition = BddDdiSetPointerPosition;
InitialData.DxgkDdiSetPointerShape = BddDdiSetPointerShape;
InitialData.DxgkDdiIsSupportedVidPn = BddDdiIsSupportedVidPn;
InitialData.DxgkDdiRecommendFunctionalVidPn = BddDdiRecommendFunctionalVidPn;
InitialData.DxgkDdiEnumVidPnCofuncModality = BddDdiEnumVidPnCofuncModality;
InitialData.DxgkDdiSetVidPnSourceVisibility = BddDdiSetVidPnSourceVisibility;
InitialData.DxgkDdiCommitVidPn = BddDdiCommitVidPn;
InitialData.DxgkDdiUpdateActiveVidPnPresentPath = BddDdiUpdateActiveVidPnPresentPath;
InitialData.DxgkDdiRecommendMonitorModes = BddDdiRecommendMonitorModes;
InitialData.DxgkDdiQueryVidPnHWCapability = BddDdiQueryVidPnHWCapability;
InitialData.DxgkDdiPresentDisplayOnly = BddDdiPresentDisplayOnly;
InitialData.DxgkDdiStopDeviceAndReleasePostDisplayOwnership = BddDdiStopDeviceAndReleasePostDisplayOwnership;
InitialData.DxgkDdiSystemDisplayEnable = BddDdiSystemDisplayEnable;
InitialData.DxgkDdiSystemDisplayWrite = BddDdiSystemDisplayWrite;
NTSTATUS Status = DxgkInitializeDisplayOnlyDriver(pDriverObject, pRegistryPath, &InitialData);
if (!NT_SUCCESS(Status))
{
BDD_LOG_ERROR1("DxgkInitializeDisplayOnlyDriver failed with Status: 0x%I64x", Status);
return Status;
}
return Status;
}
// END: Init Code
#pragma code_seg(pop)
#pragma code_seg(push)
#pragma code_seg("PAGE")
//
// PnP DDIs
//
VOID
BddDdiUnload(VOID)
{
PAGED_CODE();
}
NTSTATUS
BddDdiAddDevice(
_In_ DEVICE_OBJECT* pPhysicalDeviceObject,
_Outptr_ PVOID* ppDeviceContext)
{
PAGED_CODE();
if ((pPhysicalDeviceObject == NULL) ||
(ppDeviceContext == NULL))
{
BDD_LOG_ERROR2("One of pPhysicalDeviceObject (0x%I64x), ppDeviceContext (0x%I64x) is NULL",
pPhysicalDeviceObject, ppDeviceContext);
return STATUS_INVALID_PARAMETER;
}
*ppDeviceContext = NULL;
BASIC_DISPLAY_DRIVER* pBDD = new(NonPagedPoolNx) BASIC_DISPLAY_DRIVER(pPhysicalDeviceObject);
if (pBDD == NULL)
{
BDD_LOG_LOW_RESOURCE0("pBDD failed to be allocated");
return STATUS_NO_MEMORY;
}
*ppDeviceContext = pBDD;
return STATUS_SUCCESS;
}
NTSTATUS
BddDdiRemoveDevice(
_In_ VOID* pDeviceContext)
{
PAGED_CODE();
BASIC_DISPLAY_DRIVER* pBDD = reinterpret_cast<BASIC_DISPLAY_DRIVER*>(pDeviceContext);
if (pBDD)
{
delete pBDD;
pBDD = NULL;
}
return STATUS_SUCCESS;
}
NTSTATUS
BddDdiStartDevice(
_In_ VOID* pDeviceContext,
_In_ DXGK_START_INFO* pDxgkStartInfo,
_In_ DXGKRNL_INTERFACE* pDxgkInterface,
_Out_ ULONG* pNumberOfViews,
_Out_ ULONG* pNumberOfChildren)
{
PAGED_CODE();
BDD_ASSERT_CHK(pDeviceContext != NULL);
BASIC_DISPLAY_DRIVER* pBDD = reinterpret_cast<BASIC_DISPLAY_DRIVER*>(pDeviceContext);
return pBDD->StartDevice(pDxgkStartInfo, pDxgkInterface, pNumberOfViews, pNumberOfChildren);
}
NTSTATUS
BddDdiStopDevice(
_In_ VOID* pDeviceContext)
{
PAGED_CODE();
BDD_ASSERT_CHK(pDeviceContext != NULL);
BASIC_DISPLAY_DRIVER* pBDD = reinterpret_cast<BASIC_DISPLAY_DRIVER*>(pDeviceContext);
return pBDD->StopDevice();
}
NTSTATUS
BddDdiDispatchIoRequest(
_In_ VOID* pDeviceContext,
_In_ ULONG VidPnSourceId,
_In_ VIDEO_REQUEST_PACKET* pVideoRequestPacket)
{
PAGED_CODE();
BDD_ASSERT_CHK(pDeviceContext != NULL);
BASIC_DISPLAY_DRIVER* pBDD = reinterpret_cast<BASIC_DISPLAY_DRIVER*>(pDeviceContext);
if (!pBDD->IsDriverActive())
{
BDD_LOG_ASSERTION1("BDD (0x%I64x) is being called when not active!", pBDD);
return STATUS_UNSUCCESSFUL;
}
return pBDD->DispatchIoRequest(VidPnSourceId, pVideoRequestPacket);
}
NTSTATUS
BddDdiSetPowerState(
_In_ VOID* pDeviceContext,
_In_ ULONG HardwareUid,
_In_ DEVICE_POWER_STATE DevicePowerState,
_In_ POWER_ACTION ActionType)
{
PAGED_CODE();
BDD_ASSERT_CHK(pDeviceContext != NULL);
BASIC_DISPLAY_DRIVER* pBDD = reinterpret_cast<BASIC_DISPLAY_DRIVER*>(pDeviceContext);
if (!pBDD->IsDriverActive())
{
// If the driver isn't active, SetPowerState can still be called, however in BDD's case
// this shouldn't do anything, as it could for instance be called on BDD Fallback after
// Fallback has been stopped and BDD PnP is being started. Fallback doesn't have control
// of the hardware in this case.
return STATUS_SUCCESS;
}
return pBDD->SetPowerState(HardwareUid, DevicePowerState, ActionType);
}
NTSTATUS
BddDdiQueryChildRelations(
_In_ VOID* pDeviceContext,
_Out_writes_bytes_(ChildRelationsSize) DXGK_CHILD_DESCRIPTOR* pChildRelations,
_In_ ULONG ChildRelationsSize)
{
PAGED_CODE();
BDD_ASSERT_CHK(pDeviceContext != NULL);
BASIC_DISPLAY_DRIVER* pBDD = reinterpret_cast<BASIC_DISPLAY_DRIVER*>(pDeviceContext);
return pBDD->QueryChildRelations(pChildRelations, ChildRelationsSize);
}
NTSTATUS
BddDdiQueryChildStatus(
_In_ VOID* pDeviceContext,
_Inout_ DXGK_CHILD_STATUS* pChildStatus,
_In_ BOOLEAN NonDestructiveOnly)
{
PAGED_CODE();
BDD_ASSERT_CHK(pDeviceContext != NULL);
BASIC_DISPLAY_DRIVER* pBDD = reinterpret_cast<BASIC_DISPLAY_DRIVER*>(pDeviceContext);
return pBDD->QueryChildStatus(pChildStatus, NonDestructiveOnly);
}
NTSTATUS
BddDdiQueryDeviceDescriptor(
_In_ VOID* pDeviceContext,
_In_ ULONG ChildUid,
_Inout_ DXGK_DEVICE_DESCRIPTOR* pDeviceDescriptor)
{
PAGED_CODE();
BDD_ASSERT_CHK(pDeviceContext != NULL);
BASIC_DISPLAY_DRIVER* pBDD = reinterpret_cast<BASIC_DISPLAY_DRIVER*>(pDeviceContext);
if (!pBDD->IsDriverActive())
{
// During stress testing of PnPStop, it is possible for BDD Fallback to get called to start then stop in quick succession.
// The first call queues a worker thread item indicating that it now has a child device, the second queues a worker thread
// item that it no longer has any child device. This function gets called based on the first worker thread item, but after
// the driver has been stopped. Therefore instead of asserting like other functions, we only warn.
BDD_LOG_WARNING1("BDD (0x%I64x) is being called when not active!", pBDD);
return STATUS_UNSUCCESSFUL;
}
return pBDD->QueryDeviceDescriptor(ChildUid, pDeviceDescriptor);
}
//
// WDDM Display Only Driver DDIs
//
NTSTATUS
APIENTRY
BddDdiQueryAdapterInfo(
_In_ CONST HANDLE hAdapter,
_In_ CONST DXGKARG_QUERYADAPTERINFO* pQueryAdapterInfo)
{
PAGED_CODE();
BDD_ASSERT_CHK(hAdapter != NULL);
BASIC_DISPLAY_DRIVER* pBDD = reinterpret_cast<BASIC_DISPLAY_DRIVER*>(hAdapter);
return pBDD->QueryAdapterInfo(pQueryAdapterInfo);
}
NTSTATUS
APIENTRY
BddDdiSetPointerPosition(
_In_ CONST HANDLE hAdapter,
_In_ CONST DXGKARG_SETPOINTERPOSITION* pSetPointerPosition)
{
PAGED_CODE();
BDD_ASSERT_CHK(hAdapter != NULL);
BASIC_DISPLAY_DRIVER* pBDD = reinterpret_cast<BASIC_DISPLAY_DRIVER*>(hAdapter);
if (!pBDD->IsDriverActive())
{
BDD_LOG_ASSERTION1("BDD (0x%I64x) is being called when not active!", pBDD);
return STATUS_UNSUCCESSFUL;
}
return pBDD->SetPointerPosition(pSetPointerPosition);
}
NTSTATUS
APIENTRY
BddDdiSetPointerShape(
_In_ CONST HANDLE hAdapter,
_In_ CONST DXGKARG_SETPOINTERSHAPE* pSetPointerShape)
{
PAGED_CODE();
BDD_ASSERT_CHK(hAdapter != NULL);
BASIC_DISPLAY_DRIVER* pBDD = reinterpret_cast<BASIC_DISPLAY_DRIVER*>(hAdapter);
if (!pBDD->IsDriverActive())
{
BDD_LOG_ASSERTION1("BDD (0x%I64x) is being called when not active!", pBDD);
return STATUS_UNSUCCESSFUL;
}
return pBDD->SetPointerShape(pSetPointerShape);
}
NTSTATUS
APIENTRY
BddDdiPresentDisplayOnly(
_In_ CONST HANDLE hAdapter,
_In_ CONST DXGKARG_PRESENT_DISPLAYONLY* pPresentDisplayOnly)
{
PAGED_CODE();
BDD_ASSERT_CHK(hAdapter != NULL);
BASIC_DISPLAY_DRIVER* pBDD = reinterpret_cast<BASIC_DISPLAY_DRIVER*>(hAdapter);
if (!pBDD->IsDriverActive())
{
BDD_LOG_ASSERTION1("BDD (0x%I64x) is being called when not active!", pBDD);
return STATUS_UNSUCCESSFUL;
}
return pBDD->PresentDisplayOnly(pPresentDisplayOnly);
}
NTSTATUS
APIENTRY
BddDdiStopDeviceAndReleasePostDisplayOwnership(
_In_ VOID* pDeviceContext,
_In_ D3DDDI_VIDEO_PRESENT_TARGET_ID TargetId,
_Out_ DXGK_DISPLAY_INFORMATION* DisplayInfo)
{
PAGED_CODE();
BDD_ASSERT_CHK(pDeviceContext != NULL);
BASIC_DISPLAY_DRIVER* pBDD = reinterpret_cast<BASIC_DISPLAY_DRIVER*>(pDeviceContext);
return pBDD->StopDeviceAndReleasePostDisplayOwnership(TargetId, DisplayInfo);
}
NTSTATUS
APIENTRY
BddDdiIsSupportedVidPn(
_In_ CONST HANDLE hAdapter,
_Inout_ DXGKARG_ISSUPPORTEDVIDPN* pIsSupportedVidPn)
{
PAGED_CODE();
BDD_ASSERT_CHK(hAdapter != NULL);
BASIC_DISPLAY_DRIVER* pBDD = reinterpret_cast<BASIC_DISPLAY_DRIVER*>(hAdapter);
if (!pBDD->IsDriverActive())
{
// This path might hit because win32k/dxgport doesn't check that an adapter is active when taking the adapter lock.
// The adapter lock is the main thing BDD Fallback relies on to not be called while it's inactive. It is still a rare
// timing issue around PnpStart/Stop and isn't expected to have any effect on the stability of the system.
BDD_LOG_WARNING1("BDD (0x%I64x) is being called when not active!", pBDD);
return STATUS_UNSUCCESSFUL;
}
return pBDD->IsSupportedVidPn(pIsSupportedVidPn);
}
NTSTATUS
APIENTRY
BddDdiRecommendFunctionalVidPn(
_In_ CONST HANDLE hAdapter,
_In_ CONST DXGKARG_RECOMMENDFUNCTIONALVIDPN* CONST pRecommendFunctionalVidPn)
{
PAGED_CODE();
BDD_ASSERT_CHK(hAdapter != NULL);
BASIC_DISPLAY_DRIVER* pBDD = reinterpret_cast<BASIC_DISPLAY_DRIVER*>(hAdapter);
if (!pBDD->IsDriverActive())
{
BDD_LOG_ASSERTION1("BDD (0x%I64x) is being called when not active!", pBDD);
return STATUS_UNSUCCESSFUL;
}
return pBDD->RecommendFunctionalVidPn(pRecommendFunctionalVidPn);
}
NTSTATUS
APIENTRY
BddDdiRecommendVidPnTopology(
_In_ CONST HANDLE hAdapter,
_In_ CONST DXGKARG_RECOMMENDVIDPNTOPOLOGY* CONST pRecommendVidPnTopology)
{
PAGED_CODE();
BDD_ASSERT_CHK(hAdapter != NULL);
BASIC_DISPLAY_DRIVER* pBDD = reinterpret_cast<BASIC_DISPLAY_DRIVER*>(hAdapter);
if (!pBDD->IsDriverActive())
{
BDD_LOG_ASSERTION1("BDD (0x%I64x) is being called when not active!", pBDD);
return STATUS_UNSUCCESSFUL;
}
return pBDD->RecommendVidPnTopology(pRecommendVidPnTopology);
}
NTSTATUS
APIENTRY
BddDdiRecommendMonitorModes(
_In_ CONST HANDLE hAdapter,
_In_ CONST DXGKARG_RECOMMENDMONITORMODES* CONST pRecommendMonitorModes)
{
PAGED_CODE();
BDD_ASSERT_CHK(hAdapter != NULL);
BASIC_DISPLAY_DRIVER* pBDD = reinterpret_cast<BASIC_DISPLAY_DRIVER*>(hAdapter);
if (!pBDD->IsDriverActive())
{
BDD_LOG_ASSERTION1("BDD (0x%I64x) is being called when not active!", pBDD);
return STATUS_UNSUCCESSFUL;
}
return pBDD->RecommendMonitorModes(pRecommendMonitorModes);
}
NTSTATUS
APIENTRY
BddDdiEnumVidPnCofuncModality(
_In_ CONST HANDLE hAdapter,
_In_ CONST DXGKARG_ENUMVIDPNCOFUNCMODALITY* CONST pEnumCofuncModality)
{
PAGED_CODE();
BDD_ASSERT_CHK(hAdapter != NULL);
BASIC_DISPLAY_DRIVER* pBDD = reinterpret_cast<BASIC_DISPLAY_DRIVER*>(hAdapter);
if (!pBDD->IsDriverActive())
{
BDD_LOG_ASSERTION1("BDD (0x%I64x) is being called when not active!", pBDD);
return STATUS_UNSUCCESSFUL;
}
return pBDD->EnumVidPnCofuncModality(pEnumCofuncModality);
}
NTSTATUS
APIENTRY
BddDdiSetVidPnSourceVisibility(
_In_ CONST HANDLE hAdapter,
_In_ CONST DXGKARG_SETVIDPNSOURCEVISIBILITY* pSetVidPnSourceVisibility)
{
PAGED_CODE();
BDD_ASSERT_CHK(hAdapter != NULL);
BASIC_DISPLAY_DRIVER* pBDD = reinterpret_cast<BASIC_DISPLAY_DRIVER*>(hAdapter);
if (!pBDD->IsDriverActive())
{
BDD_LOG_ASSERTION1("BDD (0x%I64x) is being called when not active!", pBDD);
return STATUS_UNSUCCESSFUL;
}
return pBDD->SetVidPnSourceVisibility(pSetVidPnSourceVisibility);
}
NTSTATUS
APIENTRY
BddDdiCommitVidPn(
_In_ CONST HANDLE hAdapter,
_In_ CONST DXGKARG_COMMITVIDPN* CONST pCommitVidPn)
{
PAGED_CODE();
BDD_ASSERT_CHK(hAdapter != NULL);
BASIC_DISPLAY_DRIVER* pBDD = reinterpret_cast<BASIC_DISPLAY_DRIVER*>(hAdapter);
if (!pBDD->IsDriverActive())
{
BDD_LOG_ASSERTION1("BDD (0x%I64x) is being called when not active!", pBDD);
return STATUS_UNSUCCESSFUL;
}
return pBDD->CommitVidPn(pCommitVidPn);
}
NTSTATUS
APIENTRY
BddDdiUpdateActiveVidPnPresentPath(
_In_ CONST HANDLE hAdapter,
_In_ CONST DXGKARG_UPDATEACTIVEVIDPNPRESENTPATH* CONST pUpdateActiveVidPnPresentPath)
{
PAGED_CODE();
BDD_ASSERT_CHK(hAdapter != NULL);
BASIC_DISPLAY_DRIVER* pBDD = reinterpret_cast<BASIC_DISPLAY_DRIVER*>(hAdapter);
if (!pBDD->IsDriverActive())
{
BDD_LOG_ASSERTION1("BDD (0x%I64x) is being called when not active!", pBDD);
return STATUS_UNSUCCESSFUL;
}
return pBDD->UpdateActiveVidPnPresentPath(pUpdateActiveVidPnPresentPath);
}
NTSTATUS
APIENTRY
BddDdiQueryVidPnHWCapability(
_In_ CONST HANDLE hAdapter,
_Inout_ DXGKARG_QUERYVIDPNHWCAPABILITY* pVidPnHWCaps)
{
PAGED_CODE();
BDD_ASSERT_CHK(hAdapter != NULL);
BASIC_DISPLAY_DRIVER* pBDD = reinterpret_cast<BASIC_DISPLAY_DRIVER*>(hAdapter);
if (!pBDD->IsDriverActive())
{
BDD_LOG_ASSERTION1("BDD (0x%I64x) is being called when not active!", pBDD);
return STATUS_UNSUCCESSFUL;
}
return pBDD->QueryVidPnHWCapability(pVidPnHWCaps);
}
//END: Paged Code
#pragma code_seg(pop)
#pragma code_seg(push)
#pragma code_seg()
// BEGIN: Non-Paged Code
VOID
BddDdiDpcRoutine(
_In_ VOID* pDeviceContext)
{
BDD_ASSERT_CHK(pDeviceContext != NULL);
BASIC_DISPLAY_DRIVER* pBDD = reinterpret_cast<BASIC_DISPLAY_DRIVER*>(pDeviceContext);
if (!pBDD->IsDriverActive())
{
BDD_LOG_ASSERTION1("BDD (0x%I64x) is being called when not active!", pBDD);
return;
}
pBDD->DpcRoutine();
}
BOOLEAN
BddDdiInterruptRoutine(
_In_ VOID* pDeviceContext,
_In_ ULONG MessageNumber)
{
BDD_ASSERT_CHK(pDeviceContext != NULL);
BASIC_DISPLAY_DRIVER* pBDD = reinterpret_cast<BASIC_DISPLAY_DRIVER*>(pDeviceContext);
return pBDD->InterruptRoutine(MessageNumber);
}
VOID
BddDdiResetDevice(
_In_ VOID* pDeviceContext)
{
BDD_ASSERT_CHK(pDeviceContext != NULL);
BASIC_DISPLAY_DRIVER* pBDD = reinterpret_cast<BASIC_DISPLAY_DRIVER*>(pDeviceContext);
pBDD->ResetDevice();
}
NTSTATUS
APIENTRY
BddDdiSystemDisplayEnable(
_In_ VOID* pDeviceContext,
_In_ D3DDDI_VIDEO_PRESENT_TARGET_ID TargetId,
_In_ PDXGKARG_SYSTEM_DISPLAY_ENABLE_FLAGS Flags,
_Out_ UINT* Width,
_Out_ UINT* Height,
_Out_ D3DDDIFORMAT* ColorFormat)
{
BDD_ASSERT_CHK(pDeviceContext != NULL);
BASIC_DISPLAY_DRIVER* pBDD = reinterpret_cast<BASIC_DISPLAY_DRIVER*>(pDeviceContext);
return pBDD->SystemDisplayEnable(TargetId, Flags, Width, Height, ColorFormat);
}
VOID
APIENTRY
BddDdiSystemDisplayWrite(
_In_ VOID* pDeviceContext,
_In_ VOID* Source,
_In_ UINT SourceWidth,
_In_ UINT SourceHeight,
_In_ UINT SourceStride,
_In_ UINT PositionX,
_In_ UINT PositionY)
{
BDD_ASSERT_CHK(pDeviceContext != NULL);
BASIC_DISPLAY_DRIVER* pBDD = reinterpret_cast<BASIC_DISPLAY_DRIVER*>(pDeviceContext);
pBDD->SystemDisplayWrite(Source, SourceWidth, SourceHeight, SourceStride, PositionX, PositionY);
}
// END: Non-Paged Code
#pragma code_seg(pop)
+1083
View File
File diff suppressed because it is too large. Load diff
+84
View File
@@ -0,0 +1,84 @@
/******************************Module*Header*******************************\
* Module Name: BDD_ErrorLog.hxx
*
* Basic Display Driver Logging Macros
*
*
* Copyright (c) 2010 Microsoft Corporation
*
\**************************************************************************/
#ifndef _BDD_ERRORLOG_HXX_
#define _BDD_ERRORLOG_HXX_
#define BDD_LOG_ERROR0(Msg)
#define BDD_LOG_ERROR1(Msg,Param1)
#define BDD_LOG_ERROR2(Msg,Param1,Param2)
#define BDD_LOG_ERROR3(Msg,Param1,Param2,Param3)
#define BDD_LOG_ERROR4(Msg,Param1,Param2,Param3,Param4)
#define BDD_LOG_ERROR5(Msg,Param1,Param2,Param3,Param4,Param5)
//
// Warnings
//
#define BDD_LOG_WARNING0(Msg)
#define BDD_LOG_WARNING1(Msg,Param1)
#define BDD_LOG_WARNING2(Msg,Param1,Param2)
#define BDD_LOG_WARNING3(Msg,Param1,Param2,Param3)
#define BDD_LOG_WARNING4(Msg,Param1,Param2,Param3,Param4)
#define BDD_LOG_WARNING5(Msg,Param1,Param2,Param3,Param4,Param5)
//
// Events (i.e. low-frequency tracing)
//
#define BDD_LOG_EVENT0(Msg)
#define BDD_LOG_EVENT1(Msg,Param1)
#define BDD_LOG_EVENT2(Msg,Param1,Param2)
#define BDD_LOG_EVENT3(Msg,Param1,Param2,Param3)
#define BDD_LOG_EVENT4(Msg,Param1,Param2,Param3,Param4)
#define BDD_LOG_EVENT5(Msg,Param1,Param2,Param3,Param4,Param5)
//
// Information (i.e. high-frequency tracing)
//
#define BDD_LOG_INFORMATION0(Msg)
#define BDD_LOG_INFORMATION1(Msg,Param1)
#define BDD_LOG_INFORMATION2(Msg,Param1,Param2)
#define BDD_LOG_INFORMATION3(Msg,Param1,Param2,Param3)
#define BDD_LOG_INFORMATION4(Msg,Param1,Param2,Param3,Param4)
#define BDD_LOG_INFORMATION5(Msg,Param1,Param2,Param3,Param4,Param5)
//
// Low resource logging macros.
//
#define BDD_LOG_LOW_RESOURCE0(Msg)
#define BDD_LOG_LOW_RESOURCE1(Msg,Param1)
#define BDD_LOG_LOW_RESOURCE2(Msg,Param1,Param2)
#define BDD_LOG_LOW_RESOURCE3(Msg,Param1,Param2,Param3)
#define BDD_LOG_LOW_RESOURCE4(Msg,Param1,Param2,Param3,Param4)
#define BDD_LOG_LOW_RESOURCE5(Msg,Param1,Param2,Param3,Param4,Param5)
//
// Assertion logging macros.
//
#define BDD_LOG_ASSERTION0(Msg) NT_ASSERT(FALSE)
#define BDD_LOG_ASSERTION1(Msg,Param1) NT_ASSERT(FALSE)
#define BDD_LOG_ASSERTION2(Msg,Param1,Param2) NT_ASSERT(FALSE)
#define BDD_LOG_ASSERTION3(Msg,Param1,Param2,Param3) NT_ASSERT(FALSE)
#define BDD_LOG_ASSERTION4(Msg,Param1,Param2,Param3,Param4) NT_ASSERT(FALSE)
#define BDD_LOG_ASSERTION5(Msg,Param1,Param2,Param3,Param4,Param5) NT_ASSERT(FALSE)
#define BDD_ASSERT(exp) {if (!(exp)) {BDD_LOG_ASSERTION0(#exp);}}
#if DBG
#define BDD_ASSERT_CHK(exp) BDD_ASSERT(exp)
#else
#define BDD_ASSERT_CHK(exp) {}
#endif
#endif //_BDD_ERRORLOG_HXX_
+115
View File
@@ -0,0 +1,115 @@
/******************************Module*Header*******************************\
* Module Name: bdd_util.cxx
*
* Basic Display Driver utility functions
*
* Created: 29-Mar-2011
* Author: Amos Eshel [amosesh]
*
* Copyright (c) 2011 Microsoft Corporation
\**************************************************************************/
#include "BDD.hxx"
#pragma code_seg("PAGE")
//
// EDID validation
//
BOOLEAN IsEdidHeaderValid(_In_reads_bytes_(EDID_V1_BLOCK_SIZE) const BYTE* pEdid)
{
PAGED_CODE();
static const UCHAR EDID1Header[8] = {0,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0};
return memcmp(pEdid, EDID1Header, sizeof(EDID1Header)) == 0;
}
BOOLEAN IsEdidChecksumValid(_In_reads_bytes_(EDID_V1_BLOCK_SIZE) const BYTE* pEdid)
{
PAGED_CODE();
BYTE CheckSum = 0;
for (const BYTE* pEdidStart = pEdid; pEdidStart < (pEdid + EDID_V1_BLOCK_SIZE); ++pEdidStart)
{
CheckSum += *pEdidStart;
}
return CheckSum == 0;
}
//
// Frame buffer map/unmap
//
NTSTATUS
MapFrameBuffer(
_In_ PHYSICAL_ADDRESS PhysicalAddress,
_In_ ULONG Length,
_Outptr_result_bytebuffer_(Length) VOID** VirtualAddress)
{
PAGED_CODE();
//
// Check for parameters
//
if ((PhysicalAddress.QuadPart == (ULONGLONG)0) ||
(Length == 0) ||
(VirtualAddress == NULL))
{
BDD_LOG_ERROR3("One of PhysicalAddress.QuadPart (0x%I64x), Length (0x%I64x), VirtualAddress (0x%I64x) is NULL or 0",
PhysicalAddress.QuadPart, Length, VirtualAddress);
return STATUS_INVALID_PARAMETER;
}
*VirtualAddress = MmMapIoSpaceEx(PhysicalAddress,
Length,
PAGE_READWRITE | PAGE_WRITECOMBINE);
if (*VirtualAddress == NULL)
{
// The underlying call to MmMapIoSpace failed. This may be because, MmWriteCombined
// isn't supported, so try again with MmNonCached
*VirtualAddress = MmMapIoSpaceEx(PhysicalAddress,
Length,
PAGE_READWRITE | PAGE_NOCACHE);
if (*VirtualAddress == NULL)
{
BDD_LOG_LOW_RESOURCE1("MmMapIoSpace returned a NULL buffer when trying to allocate 0x%I64x bytes", Length);
return STATUS_NO_MEMORY;
}
}
return STATUS_SUCCESS;
}
NTSTATUS
UnmapFrameBuffer(
_In_reads_bytes_(Length) VOID* VirtualAddress,
_In_ ULONG Length)
{
PAGED_CODE();
//
// Check for parameters
//
if ((VirtualAddress == NULL) && (Length == 0))
{
// Allow this function to be called when there's no work to do, and treat as successful
return STATUS_SUCCESS;
}
else if ((VirtualAddress == NULL) || (Length == 0))
{
BDD_LOG_ERROR2("Only one of Length (0x%I64x), VirtualAddress (0x%I64x) is NULL or 0",
Length, VirtualAddress);
return STATUS_INVALID_PARAMETER;
}
MmUnmapIoSpace(VirtualAddress,
Length);
return STATUS_SUCCESS;
}
+346
View File
@@ -0,0 +1,346 @@
/******************************Module*Header*******************************\
* Module Name: BltFuncs.cxx
*
* Basic Display Driver copying functionality
*
*
* Copyright (c) 2010 Microsoft Corporation
\**************************************************************************/
#include "BDD.hxx"
// For the following macros, c must be a UCHAR.
#define UPPER_6_BITS(c) (((c) & rMaskTable[6 - 1]) >> 2)
#define UPPER_5_BITS(c) (((c) & rMaskTable[5 - 1]) >> 3)
#define LOWER_6_BITS(c) (((BYTE)(c)) & lMaskTable[BITS_PER_BYTE - 6])
#define LOWER_5_BITS(c) (((BYTE)(c)) & lMaskTable[BITS_PER_BYTE - 5])
#define SHIFT_FOR_UPPER_5_IN_565 (6 + 5)
#define SHIFT_FOR_MIDDLE_6_IN_565 (5)
#define SHIFT_UPPER_5_IN_565_BACK ((BITS_PER_BYTE * 2) + (BITS_PER_BYTE - 5))
#define SHIFT_MIDDLE_6_IN_565_BACK ((BITS_PER_BYTE * 1) + (BITS_PER_BYTE - 6))
#define SHIFT_LOWER_5_IN_565_BACK ((BITS_PER_BYTE * 0) + (BITS_PER_BYTE - 5))
// For the following macros, pPixel must be a BYTE* pointing to the start of a 32 bit pixel
#define CONVERT_32BPP_TO_16BPP(pPixel) ((UPPER_5_BITS(pPixel[2]) << SHIFT_FOR_UPPER_5_IN_565) | \
(UPPER_6_BITS(pPixel[1]) << SHIFT_FOR_MIDDLE_6_IN_565) | \
(UPPER_5_BITS(pPixel[0])))
// 8bpp is done with 6 levels per color channel since this gives true grays, even if it leaves 40 empty palette entries
// The 6 levels per color is the reason for dividing below by 43 (43 * 6 == 258, closest multiple of 6 to 256)
// It is also the reason for multiplying the red channel by 36 (== 6*6) and the green channel by 6, as this is the
// equivalent to bit shifting in a 3:3:2 model. Changes to this must be reflected in vesasup.cxx with the Blues/Greens/Reds arrays
#define CONVERT_32BPP_TO_8BPP(pPixel) (((pPixel[2] / 43) * 36) + \
((pPixel[1] / 43) * 6) + \
((pPixel[0] / 43)))
// 4bpp is done with strict grayscale since this has been found to be usable
// 30% of the red value, 59% of the green value, and 11% of the blue value is the standard way to convert true color to grayscale
#define CONVERT_32BPP_TO_4BPP(pPixel) ((BYTE)(((pPixel[2] * 30) + \
(pPixel[1] * 59) + \
(pPixel[0] * 11)) / (100 * 16)))
// For the following macro, Pixel must be a WORD representing a 16 bit pixel
#define CONVERT_16BPP_TO_32BPP(Pixel) (((ULONG)LOWER_5_BITS((Pixel) >> SHIFT_FOR_UPPER_5_IN_565) << SHIFT_UPPER_5_IN_565_BACK) | \
((ULONG)LOWER_6_BITS((Pixel) >> SHIFT_FOR_MIDDLE_6_IN_565) << SHIFT_MIDDLE_6_IN_565_BACK) | \
((ULONG)LOWER_5_BITS((Pixel)) << SHIFT_LOWER_5_IN_565_BACK))
#pragma code_seg(push)
#pragma code_seg()
// BEGIN: Non-Paged Code
// Bit is 1 from Idx to end of byte, with bit count starting at high order
BYTE lMaskTable[BITS_PER_BYTE] = {0xff, 0x7f, 0x3f, 0x1f, 0x0f, 0x07, 0x03, 0x01};
// Bit is 1 from Idx to start of byte, with bit count starting at high order
BYTE rMaskTable[BITS_PER_BYTE] = {0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff};
// Bit of Idx is 1, with bit count starting at high order
BYTE PixelMask[BITS_PER_BYTE] = {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01};
/****************************Internal*Routine******************************\
* CopyBits32_32
*
*
* Copies rectangles from one surface to another. Both surfaces must have
* the same resolution.
*
* OffsetX, OffsetY - to add to the rectangle coordinates.
*
* Copied from %SDXROOT%\windows\Core\dxkernel\cdd\enable.cxx (CopySurfBits)
*
\**************************************************************************/
VOID CopyBits32_32(
BLT_INFO* pDst,
CONST BLT_INFO* pSrc,
UINT NumRects,
_In_reads_(NumRects) CONST RECT *pRects)
{
NT_ASSERT((pDst->BitsPerPel == 32) &&
(pSrc->BitsPerPel == 32));
NT_ASSERT((pDst->Rotation == D3DKMDT_VPPR_IDENTITY) &&
(pSrc->Rotation == D3DKMDT_VPPR_IDENTITY));
for (UINT iRect = 0; iRect < NumRects; iRect++)
{
CONST RECT* pRect = &pRects[iRect];
NT_ASSERT(pRect->right >= pRect->left);
NT_ASSERT(pRect->bottom >= pRect->top);
UINT NumPixels = pRect->right - pRect->left;
UINT NumRows = pRect->bottom - pRect->top;
UINT BytesToCopy = NumPixels * 4;
BYTE* pStartDst = ((BYTE*)pDst->pBits +
(pRect->top + pDst->Offset.y) * pDst->Pitch +
(pRect->left + pDst->Offset.x) * 4);
CONST BYTE* pStartSrc = ((BYTE*)pSrc->pBits +
(pRect->top + pSrc->Offset.y) * pSrc->Pitch +
(pRect->left + pSrc->Offset.x) * 4);
for (UINT i = 0; i < NumRows; ++i)
{
RtlCopyMemory(pStartDst, pStartSrc, BytesToCopy);
pStartDst += pDst->Pitch;
pStartSrc += pSrc->Pitch;
}
}
}
VOID GetPitches(_In_ CONST BLT_INFO* pBltInfo, _Out_ LONG* pPixelPitch, _Out_ LONG* pRowPitch)
{
switch (pBltInfo->Rotation)
{
case D3DKMDT_VPPR_IDENTITY:
{
*pPixelPitch = (pBltInfo->BitsPerPel / BITS_PER_BYTE);
*pRowPitch = pBltInfo->Pitch;
return;
}
case D3DKMDT_VPPR_ROTATE90:
{
*pPixelPitch = -((LONG)pBltInfo->Pitch);
*pRowPitch = (pBltInfo->BitsPerPel / BITS_PER_BYTE);
return;
}
case D3DKMDT_VPPR_ROTATE180:
{
*pPixelPitch = -((LONG)pBltInfo->BitsPerPel / BITS_PER_BYTE);
*pRowPitch = -((LONG)pBltInfo->Pitch);
return;
}
case D3DKMDT_VPPR_ROTATE270:
{
*pPixelPitch = pBltInfo->Pitch;
*pRowPitch = -((LONG)pBltInfo->BitsPerPel / BITS_PER_BYTE);
return;
}
default:
{
BDD_LOG_ASSERTION1("Invalid rotation (0x%I64x) specified", pBltInfo->Rotation);
*pPixelPitch = 0;
*pRowPitch = 0;
return;
}
}
}
BYTE* GetRowStart(_In_ CONST BLT_INFO* pBltInfo, CONST RECT* pRect)
{
BYTE* pRet = NULL;
LONG OffLeft = pRect->left + pBltInfo->Offset.x;
LONG OffTop = pRect->top + pBltInfo->Offset.y;
LONG BytesPerPixel = (pBltInfo->BitsPerPel / BITS_PER_BYTE);
switch (pBltInfo->Rotation)
{
case D3DKMDT_VPPR_IDENTITY:
{
pRet = ((BYTE*)pBltInfo->pBits +
OffTop * pBltInfo->Pitch +
OffLeft * BytesPerPixel);
break;
}
case D3DKMDT_VPPR_ROTATE90:
{
pRet = ((BYTE*)pBltInfo->pBits +
(pBltInfo->Height - 1 - OffLeft) * pBltInfo->Pitch +
OffTop * BytesPerPixel);
break;
}
case D3DKMDT_VPPR_ROTATE180:
{
pRet = ((BYTE*)pBltInfo->pBits +
(pBltInfo->Height - 1 - OffTop) * pBltInfo->Pitch +
(pBltInfo->Width - 1 - OffLeft) * BytesPerPixel);
break;
}
case D3DKMDT_VPPR_ROTATE270:
{
pRet = ((BYTE*)pBltInfo->pBits +
OffLeft * pBltInfo->Pitch +
(pBltInfo->Width - 1 - OffTop) * BytesPerPixel);
break;
}
default:
{
BDD_LOG_ASSERTION1("Invalid rotation (0x%I64x) specified", pBltInfo->Rotation);
break;
}
}
return pRet;
}
/****************************Internal*Routine******************************\
* CopyBitsGeneric
*
*
* Blt function which can handle a rotated dst/src, offset rects in dst/src
* and bpp combinations of:
* dst | src
* 32 | 32 // For identity rotation this is much faster in CopyBits32_32
* 32 | 24
* 32 | 16
* 24 | 32
* 16 | 32
* 8 | 32
* 24 | 24 // untested
*
\**************************************************************************/
VOID CopyBitsGeneric(
BLT_INFO* pDst,
CONST BLT_INFO* pSrc,
UINT NumRects,
_In_reads_(NumRects) CONST RECT *pRects)
{
LONG DstPixelPitch = 0;
LONG DstRowPitch = 0;
LONG SrcPixelPitch = 0;
LONG SrcRowPitch = 0;
GetPitches(pDst, &DstPixelPitch, &DstRowPitch);
GetPitches(pSrc, &SrcPixelPitch, &SrcRowPitch);
for (UINT iRect = 0; iRect < NumRects; iRect++)
{
CONST RECT* pRect = &pRects[iRect];
NT_ASSERT(pRect->right >= pRect->left);
NT_ASSERT(pRect->bottom >= pRect->top);
UINT NumPixels = pRect->right - pRect->left;
UINT NumRows = pRect->bottom - pRect->top;
BYTE* pDstRow = GetRowStart(pDst, pRect);
CONST BYTE* pSrcRow = GetRowStart(pSrc, pRect);
for (UINT y=0; y < NumRows; y++)
{
BYTE* pDstPixel = pDstRow;
CONST BYTE* pSrcPixel = pSrcRow;
for (UINT x=0; x < NumPixels; x++)
{
if ((pDst->BitsPerPel == 24) ||
(pSrc->BitsPerPel == 24))
{
pDstPixel[0] = pSrcPixel[0];
pDstPixel[1] = pSrcPixel[1];
pDstPixel[2] = pSrcPixel[2];
// pPixel[3] is the alpha channel and is ignored for whichever of Src/Dst is 32bpp
}
else if (pDst->BitsPerPel == 32)
{
if (pSrc->BitsPerPel == 32)
{
UINT32* pDstPixelAs32 = (UINT32*)pDstPixel;
UINT32* pSrcPixelAs32 = (UINT32*)pSrcPixel;
*pDstPixelAs32 = *pSrcPixelAs32;
}
else if (pSrc->BitsPerPel == 16)
{
UINT32* pDstPixelAs32 = (UINT32*)pDstPixel;
UINT16* pSrcPixelAs16 = (UINT16*)pSrcPixel;
*pDstPixelAs32 = CONVERT_16BPP_TO_32BPP(*pSrcPixelAs16);
}
else
{
// Invalid pSrc->BitsPerPel on a pDst->BitsPerPel of 32
NT_ASSERT(FALSE);
}
}
else if (pDst->BitsPerPel == 16)
{
NT_ASSERT(pSrc->BitsPerPel == 32);
UINT16* pDstPixelAs16 = (UINT16*)pDstPixel;
*pDstPixelAs16 = CONVERT_32BPP_TO_16BPP(pSrcPixel);
}
else if (pDst->BitsPerPel == 8)
{
NT_ASSERT(pSrc->BitsPerPel == 32);
*pDstPixel = CONVERT_32BPP_TO_8BPP(pSrcPixel);
}
else
{
// Invalid pDst->BitsPerPel
NT_ASSERT(FALSE);
}
pDstPixel += DstPixelPitch;
pSrcPixel += SrcPixelPitch;
}
pDstRow += DstRowPitch;
pSrcRow += SrcRowPitch;
}
}
}
/****************************Internal*Routine******************************\
* BltBits
*
*
* Logic to decide which of the above functions to call based on Rotation/BPP
*
\**************************************************************************/
VOID BltBits(
BLT_INFO* pDst,
CONST BLT_INFO* pSrc,
UINT NumRects,
_In_reads_(NumRects) CONST RECT *pRects)
{
// pSrc->pBits might be coming from user-mode. User-mode addresses when accessed by kernel need to be protected by a __try/__except.
// This usage is redundant in the sample driver since it is already being used for MmProbeAndLockPages. However, it is very important
// to have this in place and to make sure developers don't miss it, it is in these two locations.
__try
{
if (pDst->BitsPerPel == 32 &&
pSrc->BitsPerPel == 32 &&
pDst->Rotation == D3DKMDT_VPPR_IDENTITY &&
pSrc->Rotation == D3DKMDT_VPPR_IDENTITY)
{
// This is by far the most common copy function being called
CopyBits32_32(pDst, pSrc, NumRects, pRects);
}
else
{
CopyBitsGeneric(pDst, pSrc, NumRects, pRects);
}
}
#pragma prefast(suppress: __WARNING_EXCEPTIONEXECUTEHANDLER, "try/except is only able to protect against user-mode errors and these are the only errors we try to catch here");
__except(EXCEPTION_EXECUTE_HANDLER)
{
BDD_LOG_ERROR2("Either dst (0x%I64x) or src (0x%I64x) bits encountered exception during access.", pDst->pBits, pSrc->pBits);
}
}
// END: Non-Paged Code
#pragma code_seg(pop)
+556
View File
@@ -0,0 +1,556 @@
/******************************Module*Header*******************************\
* Module Name: blthw.cxx
*
* Sample display driver functions for a HW blt simulation. This file is
* only provided to simulate how a real hardware-accelerated display-only
* driver functions, and should not be used in a real driver.
*
* Copyright (c) 2011 Microsoft Corporation
\**************************************************************************/
#include "BDD.hxx"
typedef struct
{
CONST DXGKRNL_INTERFACE* DxgkInterface;
DXGKARGCB_NOTIFY_INTERRUPT_DATA NotifyInterrupt;
} SYNC_NOTIFY_INTERRUPT;
KSYNCHRONIZE_ROUTINE SynchronizeVidSchNotifyInterrupt;
BOOLEAN SynchronizeVidSchNotifyInterrupt(_In_opt_ PVOID params)
{
// This routine is non-paged code called at the device interrupt level (DIRQL)
// to notify VidSch and schedule a DPC. It is meant as a demonstration of handling
// a real hardware interrupt, even though it is actually called from asynchronous
// present worker threads in this sample.
SYNC_NOTIFY_INTERRUPT* pParam = reinterpret_cast<SYNC_NOTIFY_INTERRUPT*>(params);
// The context is known to be non-NULL
__analysis_assume(pParam != NULL);
// Update driver information related to fences
switch(pParam->NotifyInterrupt.InterruptType)
{
case DXGK_INTERRUPT_DISPLAYONLY_VSYNC:
case DXGK_INTERRUPT_DISPLAYONLY_PRESENT_PROGRESS:
break;
default:
NT_ASSERT(FALSE);
return FALSE;
}
// Callback OS to report about the interrupt
pParam->DxgkInterface->DxgkCbNotifyInterrupt(pParam->DxgkInterface->DeviceHandle,&pParam->NotifyInterrupt);
// Now queue a DPC for this interrupt (to callback schedule at DCP level and let it do more work there)
// DxgkCbQueueDpc can return FALSE if there is already a DPC queued
// this is an acceptable condition
pParam->DxgkInterface->DxgkCbQueueDpc(pParam->DxgkInterface->DeviceHandle);
return TRUE;
}
#pragma code_seg("PAGE")
KSTART_ROUTINE HwContextWorkerThread;
struct DoPresentMemory
{
PVOID DstAddr;
UINT DstStride;
ULONG DstBitPerPixel;
UINT SrcWidth;
UINT SrcHeight;
BYTE* SrcAddr;
LONG SrcPitch;
ULONG NumMoves; // in: Number of screen to screen moves
D3DKMT_MOVE_RECT* Moves; // in: Point to the list of moves
ULONG NumDirtyRects; // in: Number of direct rects
RECT* DirtyRect; // in: Point to the list of dirty rects
D3DKMDT_VIDPN_PRESENT_PATH_ROTATION Rotation;
BOOLEAN SynchExecution;
D3DDDI_VIDEO_PRESENT_SOURCE_ID SourceID;
HANDLE hAdapter;
PMDL Mdl;
BDD_HWBLT* DisplaySource;
};
void
HwExecutePresentDisplayOnly(
HANDLE Context);
NTSTATUS
StartHwBltPresentWorkerThread(
_In_ PKSTART_ROUTINE StartRoutine,
_In_ _When_(return==0, __drv_aliasesMem) PVOID StartContext)
/*++
Routine Description:
This routine creates the worker thread to execute a single present
command. Creating a new thread on every asynchronous present is not
efficient, but this file is only meant as a simulation, not an example
of implementation.
Arguments:
StartRoutine - start routine
StartContext - start context
Return Value:
Status
--*/
{
PAGED_CODE();
OBJECT_ATTRIBUTES ObjectAttributes;
InitializeObjectAttributes(&ObjectAttributes, NULL, OBJ_KERNEL_HANDLE, NULL, NULL);
HANDLE hWorkerThread = NULL;
// copy data from the context which is need here, as it will be deleted in separate thread
DoPresentMemory* ctx = reinterpret_cast<DoPresentMemory*>(StartContext);
BDD_HWBLT* displaySource = ctx->DisplaySource;
NTSTATUS Status = PsCreateSystemThread(
&hWorkerThread,
THREAD_ALL_ACCESS,
&ObjectAttributes,
NULL,
NULL,
StartRoutine,
StartContext);
if (!NT_SUCCESS(Status))
{
return Status;
}
// wait for thread to start - infinite wait -
// need to make sure the tread is running before OS stars submitting the work items to it
KeWaitForSingleObject(&displaySource->m_hThreadStartupEvent, Executive, KernelMode, FALSE, NULL);
// Handle is passed to the parent object which must close it
displaySource->SetPresentWorkerThreadInfo(hWorkerThread);
// Resume context thread, this is done by setting the event the thread is waiting on
KeSetEvent(&displaySource->m_hThreadSuspendEvent, 0, FALSE);
return STATUS_PENDING;
}
BDD_HWBLT::BDD_HWBLT():m_DevExt (NULL),
m_SynchExecution(TRUE),
m_hPresentWorkerThread(NULL),
m_pPresentWorkerThread(NULL)
{
PAGED_CODE();
KeInitializeEvent(&m_hThreadStartupEvent, NotificationEvent, FALSE);
KeInitializeEvent(&m_hThreadSuspendEvent, SynchronizationEvent, FALSE);
}
BDD_HWBLT::~BDD_HWBLT()
/*++
Routine Description:
This routine waits on present worker thread to exit before
destroying the object
Arguments:
None
Return Value:
None
--*/
{
PAGED_CODE();
// make sure the worker thread has exited
SetPresentWorkerThreadInfo(NULL);
}
#pragma warning(push)
#pragma warning(disable:26135) // The function doesn't lock anything
void
BDD_HWBLT::SetPresentWorkerThreadInfo(
HANDLE hWorkerThread)
/*++
Routine Description:
The method is updating present worker information
It is called in following cases:
- In ExecutePresent to update worker thread information
- In Dtor to wait on worker thread to exit
Arguments:
hWorkerThread - handle of the present worker thread
Return Value:
None
--*/
{
PAGED_CODE();
if (m_pPresentWorkerThread)
{
// Wait for thread to exit
KeWaitForSingleObject(m_pPresentWorkerThread, Executive, KernelMode,
FALSE, NULL);
// Dereference thread object
ObDereferenceObject(m_pPresentWorkerThread);
m_pPresentWorkerThread = NULL;
NT_ASSERT(m_hPresentWorkerThread);
ZwClose(m_hPresentWorkerThread);
m_hPresentWorkerThread = NULL;
}
if (hWorkerThread)
{
// Make sure that thread's handle would be valid even if the thread exited
ObReferenceObjectByHandle(hWorkerThread, THREAD_ALL_ACCESS, NULL,
KernelMode, &m_pPresentWorkerThread, NULL);
NT_ASSERT(m_pPresentWorkerThread);
m_hPresentWorkerThread = hWorkerThread;
}
}
#pragma warning(pop)
NTSTATUS
BDD_HWBLT::ExecutePresentDisplayOnly(
_In_ BYTE* DstAddr,
_In_ UINT DstBitPerPixel,
_In_ BYTE* SrcAddr,
_In_ UINT SrcBytesPerPixel,
_In_ LONG SrcPitch,
_In_ ULONG NumMoves,
_In_ D3DKMT_MOVE_RECT* Moves,
_In_ ULONG NumDirtyRects,
_In_ RECT* DirtyRect,
_In_ D3DKMDT_VIDPN_PRESENT_PATH_ROTATION Rotation)
/*++
Routine Description:
The method creates present worker thread and provides context
for it filled with present commands
Arguments:
DstAddr - address of destination surface
DstBitPerPixel - color depth of destination surface
SrcAddr - address of source surface
SrcBytesPerPixel - bytes per pixel of source surface
SrcPitch - source surface pitch (bytes in a row)
NumMoves - number of moves to be copied
Moves - moves' data
NumDirtyRects - number of rectangles to be copied
DirtyRect - rectangles' data
Rotation - roatation to be performed when executing copy
CallBack - callback for present worker thread to report execution status
Return Value:
Status
--*/
{
PAGED_CODE();
NTSTATUS Status = STATUS_SUCCESS;
SIZE_T sizeMoves = NumMoves*sizeof(D3DKMT_MOVE_RECT);
SIZE_T sizeRects = NumDirtyRects*sizeof(RECT);
SIZE_T size = sizeof(DoPresentMemory) + sizeMoves + sizeRects;
DoPresentMemory* ctx = reinterpret_cast<DoPresentMemory*>
(new (PagedPool) BYTE[size]);
if (!ctx)
{
return STATUS_NO_MEMORY;
}
RtlZeroMemory(ctx,size);
const CURRENT_BDD_MODE* pModeCur = m_DevExt->GetCurrentMode(m_SourceId);
ctx->DstAddr = DstAddr;
ctx->DstBitPerPixel = DstBitPerPixel;
ctx->DstStride = pModeCur->DispInfo.Pitch;
ctx->SrcWidth = pModeCur->SrcModeWidth;
ctx->SrcHeight = pModeCur->SrcModeHeight;
ctx->SrcAddr = NULL;
ctx->SrcPitch = SrcPitch;
ctx->Rotation = Rotation;
ctx->NumMoves = NumMoves;
ctx->Moves = Moves;
ctx->NumDirtyRects = NumDirtyRects;
ctx->DirtyRect = DirtyRect;
ctx->SourceID = m_SourceId;
ctx->hAdapter = m_DevExt;
ctx->Mdl = NULL;
ctx->DisplaySource = this;
// Alternate between synch and asynch execution, for demonstrating
// that a real hardware implementation can do either
m_SynchExecution = !m_SynchExecution;
ctx->SynchExecution = m_SynchExecution;
{
// Map Source into kernel space, as Blt will be executed by system worker thread
UINT sizeToMap = SrcBytesPerPixel*pModeCur->SrcModeWidth*pModeCur->SrcModeHeight;
PMDL mdl = IoAllocateMdl((PVOID)SrcAddr, sizeToMap, FALSE, FALSE, NULL);
if(!mdl)
{
return STATUS_INSUFFICIENT_RESOURCES;
}
KPROCESSOR_MODE AccessMode = static_cast<KPROCESSOR_MODE>(( SrcAddr <=
(BYTE* const) MM_USER_PROBE_ADDRESS)?UserMode:KernelMode);
__try
{
// Probe and lock the pages of this buffer in physical memory.
// We need only IoReadAccess.
MmProbeAndLockPages(mdl, AccessMode, IoReadAccess);
}
#pragma prefast(suppress: __WARNING_EXCEPTIONEXECUTEHANDLER, "try/except is only able to protect against user-mode errors and these are the only errors we try to catch here");
__except(EXCEPTION_EXECUTE_HANDLER)
{
Status = GetExceptionCode();
IoFreeMdl(mdl);
return Status;
}
// Map the physical pages described by the MDL into system space.
// Note: double mapping the buffer this way causes lot of system
// overhead for large size buffers.
ctx->SrcAddr = reinterpret_cast<BYTE*>
(MmGetSystemAddressForMdlSafe(mdl, NormalPagePriority ));
if(!ctx->SrcAddr) {
Status = STATUS_INSUFFICIENT_RESOURCES;
MmUnlockPages(mdl);
IoFreeMdl(mdl);
return Status;
}
// Save Mdl to unmap and unlock the pages in worker thread
ctx->Mdl = mdl;
}
BYTE* rects = reinterpret_cast<BYTE*>(ctx+1);
// copy moves and update pointer
if (Moves)
{
memcpy(rects,Moves,sizeMoves);
ctx->Moves = reinterpret_cast<D3DKMT_MOVE_RECT*>(rects);
rects += sizeMoves;
}
// copy dirty rects and update pointer
if (DirtyRect)
{
memcpy(rects,DirtyRect,sizeRects);
ctx->DirtyRect = reinterpret_cast<RECT*>(rects);
}
if (m_SynchExecution)
{
HwExecutePresentDisplayOnly((PVOID)ctx);
return STATUS_SUCCESS;
}
else
{
// Create a worker thread to perform the present asynchronously
// Ctx will be deleted in worker thread (on exit)
return StartHwBltPresentWorkerThread(HwContextWorkerThread,(PVOID)ctx);
}
}
void
ReportPresentProgress(
_In_ HANDLE Adapter,
_In_ D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId,
_In_ BOOLEAN CompletedOrFailed)
/*++
Routine Description:
This routine runs a fake interrupt routine in order to tell the OS about the present progress.
Arguments:
Adapter - Handle to the adapter (Device Extension)
VidPnSourceId - Video present source id for the callback
CompletedOrFailed - Present progress status for the source
Return Value:
None
--*/
{
PAGED_CODE();
BASIC_DISPLAY_DRIVER* pDevExt =
reinterpret_cast<BASIC_DISPLAY_DRIVER*>(Adapter);
SYNC_NOTIFY_INTERRUPT SyncNotifyInterrupt = {};
SyncNotifyInterrupt.DxgkInterface = pDevExt->GetDxgkInterface();
SyncNotifyInterrupt.NotifyInterrupt.InterruptType = DXGK_INTERRUPT_DISPLAYONLY_PRESENT_PROGRESS;
SyncNotifyInterrupt.NotifyInterrupt.DisplayOnlyPresentProgress.VidPnSourceId = VidPnSourceId;
SyncNotifyInterrupt.NotifyInterrupt.DisplayOnlyPresentProgress.ProgressId =
(CompletedOrFailed)?DXGK_PRESENT_DISPLAYONLY_PROGRESS_ID_COMPLETE:
DXGK_PRESENT_DISPLAYONLY_PROGRESS_ID_FAILED;
// Execute the SynchronizeVidSchNotifyInterrupt function at the interrupt
// IRQL in order to fake a real present progress interrupt
BOOLEAN bRet = FALSE;
NT_VERIFY(NT_SUCCESS(pDevExt->GetDxgkInterface()->DxgkCbSynchronizeExecution(
pDevExt->GetDxgkInterface()->DeviceHandle,
(PKSYNCHRONIZE_ROUTINE)SynchronizeVidSchNotifyInterrupt,
(PVOID)&SyncNotifyInterrupt,0,&bRet)));
NT_ASSERT(bRet);
}
void
HwContextWorkerThread(
HANDLE Context)
{
PAGED_CODE();
DoPresentMemory* ctx = reinterpret_cast<DoPresentMemory*>(Context);
BDD_HWBLT* displaySource = ctx->DisplaySource;
// Signal event to indicate that the tread has started
KeSetEvent(&displaySource->m_hThreadStartupEvent, 0, FALSE);
// Suspend context thread, do this by waiting on the suspend event
KeWaitForSingleObject(&displaySource->m_hThreadSuspendEvent, Executive, KernelMode, FALSE, NULL);
HwExecutePresentDisplayOnly(Context);
}
void
HwExecutePresentDisplayOnly(
HANDLE Context)
/*++
Routine Description:
The routine executes present's commands and report progress to the OS
Arguments:
Context - Context with present's command
Return Value:
None
--*/
{
PAGED_CODE();
DoPresentMemory* ctx = reinterpret_cast<DoPresentMemory*>(Context);
// Set up destination blt info
BLT_INFO DstBltInfo;
DstBltInfo.pBits = ctx->DstAddr;
DstBltInfo.Pitch = ctx->DstStride;
DstBltInfo.BitsPerPel = ctx->DstBitPerPixel;
DstBltInfo.Offset.x = 0;
DstBltInfo.Offset.y = 0;
DstBltInfo.Rotation = ctx->Rotation;
DstBltInfo.Width = ctx->SrcWidth;
DstBltInfo.Height = ctx->SrcHeight;
// Set up source blt info
BLT_INFO SrcBltInfo;
SrcBltInfo.pBits = ctx->SrcAddr;
SrcBltInfo.Pitch = ctx->SrcPitch;
SrcBltInfo.BitsPerPel = 32;
SrcBltInfo.Offset.x = 0;
SrcBltInfo.Offset.y = 0;
SrcBltInfo.Rotation = D3DKMDT_VPPR_IDENTITY;
if (ctx->Rotation == D3DKMDT_VPPR_ROTATE90 ||
ctx->Rotation == D3DKMDT_VPPR_ROTATE270)
{
SrcBltInfo.Width = DstBltInfo.Height;
SrcBltInfo.Height = DstBltInfo.Width;
}
else
{
SrcBltInfo.Width = DstBltInfo.Width;
SrcBltInfo.Height = DstBltInfo.Height;
}
// Copy all the scroll rects from source image to video frame buffer.
for (UINT i = 0; i < ctx->NumMoves; i++)
{
BltBits(&DstBltInfo,
&SrcBltInfo,
1, // NumRects
&ctx->Moves[i].DestRect);
}
// Copy all the dirty rects from source image to video frame buffer.
for (UINT i = 0; i < ctx->NumDirtyRects; i++)
{
BltBits(&DstBltInfo,
&SrcBltInfo,
1, // NumRects
&ctx->DirtyRect[i]);
}
// Unmap unmap and unlock the pages.
if (ctx->Mdl)
{
MmUnlockPages(ctx->Mdl);
IoFreeMdl(ctx->Mdl);
}
if(ctx->SynchExecution)
{
// This code simulates Blt executed synchronously
// nothing should be done here, just exit
;
}
else
{
// TRUE == completed
// This code is emulates interrupt which HW should generate
ReportPresentProgress(ctx->hAdapter,ctx->SourceID,TRUE);
}
delete [] reinterpret_cast<BYTE*>(ctx);
}
+90
View File
@@ -0,0 +1,90 @@
/******************************Module*Header*******************************\
* Module Name: bdd.h
*
* Basic Display Driver memory allocation, deletion, and tracking
*
*
* Copyright (c) 2010 Microsoft Corporation
\**************************************************************************/
#include "BDD.hxx"
#pragma code_seg("PAGE")
//
// New and delete operators
//
_When_((PoolType & NonPagedPoolMustSucceed) != 0,
__drv_reportError("Must succeed pool allocations are forbidden. "
"Allocation failures cause a system crash"))
void* __cdecl operator new(size_t Size, POOL_TYPE PoolType)
{
PAGED_CODE();
Size = (Size != 0) ? Size : 1;
void* pObject = ExAllocatePool2(PoolType, Size, BDDTAG);
#if DBG
if (pObject != NULL)
{
RtlFillMemory(pObject, Size, 0xCD);
}
#endif // DBG
return pObject;
}
_When_((PoolType & NonPagedPoolMustSucceed) != 0,
__drv_reportError("Must succeed pool allocations are forbidden. "
"Allocation failures cause a system crash"))
void* __cdecl operator new[](size_t Size, POOL_TYPE PoolType)
{
PAGED_CODE();
Size = (Size != 0) ? Size : 1;
void* pObject = ExAllocatePool2(PoolType, Size, BDDTAG);
#if DBG
if (pObject != NULL)
{
RtlFillMemory(pObject, Size, 0xCD);
}
#endif // DBG
return pObject;
}
void __cdecl operator delete(void* pObject)
{
PAGED_CODE();
if (pObject != NULL)
{
ExFreePool(pObject);
}
}
//
// size_t version is needed for VS2015(C++ 14).
//
void __cdecl operator delete(void* pObject, size_t s)
{
PAGED_CODE();
UNREFERENCED_PARAMETER( s );
::operator delete( pObject );
}
void __cdecl operator delete[](void* pObject)
{
PAGED_CODE();
if (pObject != NULL)
{
ExFreePool(pObject);
}
}
+30
View File
@@ -0,0 +1,30 @@
/*++
Copyright (c) 2011 Microsoft Corporation
Module Name:
SampleDisplay.rc
Abstract:
This modules contains the version information for the Sample Display Driver
Environment:
Kernel mode only
--*/
#include <windows.h>
#include <ntverp.h>
#define VER_FILETYPE VFT_DRV
#define VER_FILESUBTYPE VFT2_DRV_DISPLAY
#define VER_FILEDESCRIPTION_STR "Microsoft Sample Display Driver"
#define VER_INTERNALNAME_STR "SampleDisplay.sys"
#define VER_ORIGINALFILENAME_STR "SampleDisplay.sys"
#define VER_LANGNEUTRAL
#include "common.ver"
+103 -19
View File
@@ -1,14 +1,19 @@
# Virtual Display Driver
based on Microsoft Indirect Display Driver Sample.
based on Microsoft Indirect Display Driver Sample. This creates a virtual display in Windows that acts and functions just like a real one. It's useful for streaming, virtual reality applications, recording, headless servers, etc. The benefit over a physical display is the ability to adjust resolutions and refresh rates beyond the physical displays capabilities. For example, this would enable the ability to stream a game from your home PC using game streaming software at 240hz at 8K while owning a 60hz 1080p monitor (unrealistic, but explains the abilities well). For servers without displays, this enabled remote desktop and screen streaming to other systems as if there were a display installed.
Supports emulating resolutions from 640 x 480 to 7680 x 4320 (8K), and refresh rates including 60hz, 75hz, 120hz, 144hz, and 240hz.
Supports emulating resolutions from **640 x 480** to **7680 x 4320 (8K)**, and refresh rates including **60hz, 75hz, 90hz, 120hz, 144hz, 165hz, 240hz, 480hz,** and **500hz.**
This project uses the official Windows Indirect Display Driver combined with the IddCx class extension driver.
## Download
- [Windows 10 and 11 (no HDR)](https://github.com/itsmikethetech/Virtual-Display-Driver/releases/tag/23.10.20.2)
- [Windows 11 22H2+ (HDR)](https://github.com/itsmikethetech/Virtual-Display-Driver/releases/tag/23.12.2HDR)
## Installation
1. Download the latest version from the releases page, and extract the contents to a folder.
**2. Copy `option.txt` to `C:\IddSampleDriver\option.txt` before installing the driver (important!)**.
2. Copy `option.txt` to `C:\IddSampleDriver\option.txt` before installing the driver **(important!)**.
3. Right click and run the *.bat file **as an Administrator** to add the driver certificate as a trusted root certificate.
4. Don't install the inf. Open device manager, click on any device, then click on the "Action" menu and click "Add Legacy Hardware".
5. Select "Add hardware from a list (Advanced)" and then select Display adapters
@@ -16,6 +21,24 @@ This project uses the official Windows Indirect Display Driver combined with the
7. You are done! Go to display settings to customize the resolution of the additional displays. These displays show up in Sunshine, your Oculus or VR settings, and should be able to be streamed from.
8. You can enable/disable the display adapter to toggle the monitors.
Ps. Make sure that options.txt is accesible for the system at `C:\IddSampleDriver\option.txt` or the installation will fail.
## Uninstalling
1. Open device manager
2. Locate Display Adapters
3. Right click on IddSampleDriver, choose "Uninstall device"
4. There is a new popup window, in there click Attempt to remove driver for this device.
Next instructions are for those cases where the device is removed from the system, but driver stil remains. This happens when there is a connection to the device while trying to remove the drivers. To
remedy this, there is a a few tricks built into windows. So here goes:
5. Open up a powershell terminal and input this:
6. ```pnputil /enum-drivers```
6. Locate iddsampledriver.inf, there might be multiple pages of text. Make a note of the "published name", it's often unique for your system, but might look like "oem139.inf"
7. ```pnputil /delete-driver oem139.inf```
## HDR Support Now Available for Windows 11 22H2+
### Resolutions:
@@ -23,7 +46,6 @@ This project uses the official Windows Indirect Display Driver combined with the
800 x 600
1024 x 768
1152 x 864
1280 x 600
1280 x 720
1280 x 768
1280 x 800
@@ -31,47 +53,95 @@ This project uses the official Windows Indirect Display Driver combined with the
1280 x 1024
1360 x 768
1366 x 768
1400 x 1050
1440 x 900
1400 x 1050
1440 x 1440
1600 x 900
1680 x 1050
1600 x 1024
1680 x 1050
1920 x 1080
1920 x 1200
1920 x 1440
2560 x 1440
2560 x 1600
2732 x 2048
2880 x 1620
2880 x 1800
3008 x 1692
3200 x 1800
3200 x 2400
3840 x 2160
3840 x 2400
4096 x 2304
4096 x 2560
5120 x 2880
6016 x 3384
7680 x 4320
### Just Added!
2732 x 2048
2560 x 1080
2880 x 1200
3440 x 1440
3840 x 1600
4320 x 1800
5120 x 2160
5760 x 2400
6880 x 2880
7680 x 3200
8640 x 3600
10240 x 432
2880 x 900
3840 x 1080
3840 x 1200
4320 x 1200
5120 x 1440
5120 x 1600
5760 x 1600
5760 x 1800
6400 x 1800
6480 x 1800
7680 x 2160
7680 x 2400
8640 x 2400
2388 x 1668
2400 x 1080
3456 x 2234
3456 x 2234
### Refresh Rates:
30Hz
60Hz
75Hz
90Hz (Great for VR!)
120Hz
144Hz
165Hz
240Hz
480Hz
500Hz
### Videos
[![thumbnail2023](https://github.com/itsmikethetech/Virtual-Display-Driver/assets/25166211/1a64c390-5d8a-420f-8bb9-4642349fc132)](https://youtu.be/nNWpbRUPkn4 "How to install a virtual display")
[Previous Video: How to install a virtual display](https://youtu.be/byfBWDnToYk "How to install a virtual display")
### Screenshots:
![image](https://github.com/itsmikethetech/Virtual-Display-Driver/assets/25166211/0f1dfed6-c9ac-4cb6-92cf-7d9ab2ac0c66)
![image](https://github.com/itsmikethetech/Virtual-Display-Driver/assets/25166211/5cb8ce08-890f-4bc1-a1a6-34f22e103699)
![image](https://github.com/itsmikethetech/Virtual-Display-Driver/assets/25166211/02af86f2-b896-4265-9174-b17c9a1aeab7)
## Background reading ##
Start at the [Indirect Display Driver Model Overview](https://msdn.microsoft.com/en-us/library/windows/hardware/mt761968(v=vs.85).aspx) on MSDN.
## Customizing the sample ##
The sample driver code is very simplistic and does nothing more than enumerate a single monitor when its device enters the D0/started power state. Throughout the code, there are `TODO` blocks with important information on implementing functionality in a production driver.
### Code structure ###
The sample driver code is very simplistic and does nothing more than enumerate a single monitor when its device enters the D0/started power state. The IDD runs in Session 0 without any components running in the user session, so any driver instability will not affect the stability of the system as a whole. The IDD is a user-mode only model with no support for kernel-mode components. As such, the driver is able to use any DirectX APIs in order to process the desktop image. In fact, the IddCx provides the desktop image to encode in a DirectX surface.
* `Direct3DDevice` class
* Contains logic for enumerating the correct render GPU from DXGI and creating a D3D device.
* Manages the lifetime of a DXGI factory and a D3D device created for the render GPU the system is using to render frames for your indirect display device's swap-chain.
@@ -85,16 +155,30 @@ The sample driver code is very simplistic and does nothing more than enumerate a
## License
License MIT and CC0 or Public Domain (for changes I made, check with Microsoft for their license), whichever is least restrictive -- Use it
MIT and CC0 or Public Domain (for changes I made, please consult Microsoft for their license), choose the least restrictive option.
AS IS - NO IMPLICIT OR EXPLICIT warranty This may break your computer, it didn't break mine. It runs in User Mode which means it's less likely to cause system instability like the Blue Screen of Death.
## Disclaimer:
This software is provided "AS IS" with NO IMPLICIT OR EXPLICIT warranty. It's worth noting that while this software functioned without issues on my system, there is no guarantee that it will not impact your computer. It operates in User Mode, which reduces the likelihood of causing system instability, such as the Blue Screen of Death. However, exercise caution when using this software.
## Acknowledgements
Shoutout to Roshkins for the original repo:
Shoutout to **Roshkins** for the original repo:
https://github.com/roshkins/IddSampleDriver
Microsoft Indirect Display Driver/Sample (Driver code):
Shoutout to **Baloukj** for the 8-bit / 10-bit support. (Also, first to push the new Microsoft Driver public!)
https://github.com/baloukj/IddSampleDriver
Shoutout to **Anakngtokwa** for assisting with finding driver sources.
**Microsoft** Indirect Display Driver/Sample (Driver code):
https://github.com/microsoft/Windows-driver-samples/tree/master/video/IndirectDisplay
Thanks to https://github.com/akatrevorjay/edid-generator for the hi-res EDID.
Thanks to **AKATrevorJay** https://github.com/akatrevorjay/edid-generator for the hi-res EDID.
Shoutout to **zjoasan** and **Bud** for the helper scripts and build support!
## Star History
[![Star History Chart](https://api.star-history.com/svg?repos=itsmikethetech/Virtual-Display-Driver&type=Date)](https://star-history.com/#itsmikethetech/Virtual-Display-Driver&Date)
+72 -175
View File
@@ -1,176 +1,73 @@
1
#lines beginning with "#" are ignored (comment)
#the first line must be a positive integer (small number (<5) is recommended)), NOT comment
#(currently) the location of this file must be "C:\IddSampleDriver\option.txt" (hard-coded)
#numbers should be separated by comma
#spaces before number are allowed
640, 480, 60
640, 480, 75
640, 480, 120
640, 480, 144
640, 480, 240
800, 600, 60
800, 600, 75
800, 600, 120
800, 600, 144
800, 600, 240
1024, 768, 60
1024, 768, 75
1024, 768, 120
1024, 768, 144
1024, 768, 240
1152, 864, 60
1152, 864, 75
1152, 864, 120
1152, 864, 144
1152, 864, 240
1280, 600, 60
1280, 600, 75
1280, 600, 120
1280, 600, 144
1280, 600, 240
1280, 720, 60
1280, 720, 75
1280, 720, 120
1280, 720, 144
1280, 720, 240
1280, 768, 60
1280, 768, 75
1280, 768, 120
1280, 768, 144
1280, 768, 240
1280, 800, 60
1280, 800, 75
1280, 800, 120
1280, 800, 144
1280, 800, 240
1280, 960, 60
1280, 960, 75
1280, 960, 120
1280, 960, 144
1280, 960, 240
1280, 1024, 60
1280, 1024, 75
1280, 1024, 120
1280, 1024, 144
1280, 1024, 240
1360, 768, 60
1360, 768, 75
1360, 768, 120
1360, 768, 144
1360, 768, 240
1366, 768, 60
1366, 768, 75
1366, 768, 120
1366, 768, 144
1366, 768, 240
1400, 1050, 60
1400, 1050, 75
1400, 1050, 120
1400, 1050, 144
1400, 1050, 240
1440, 900, 60
1440, 900, 75
1440, 900, 120
1440, 900, 144
1440, 900, 240
1600, 900, 60
1600, 900, 75
1600, 900, 120
1600, 900, 144
1600, 900, 240
1680, 1050, 60
1680, 1050, 75
1680, 1050, 120
1680, 1050, 144
1680, 1050, 240
1600, 1024, 60
1600, 1024, 75
1600, 1024, 120
1600, 1024, 144
1600, 1024, 240
1920, 1080, 60
1920, 1080, 75
1920, 1080, 120
1920, 1080, 144
1920, 1080, 240
1920, 1200, 60
1920, 1200, 75
1920, 1200, 120
1920, 1200, 144
1920, 1200, 240
1920, 1440, 60
1920, 1440, 75
1920, 1440, 120
1920, 1440, 144
1920, 1440, 240
2560, 1440, 60
2560, 1440, 75
2560, 1440, 120
2560, 1440, 144
2560, 1440, 240
2560, 1600, 60
2560, 1600, 75
2560, 1600, 120
2560, 1600, 144
2560, 1600, 240
2880, 1620, 60
2880, 1620, 75
2880, 1620, 120
2880, 1620, 144
2880, 1620, 240
2880, 1800, 60
2880, 1800, 75
2880, 1800, 120
2880, 1800, 144
2880, 1800, 240
3008, 1692, 60
3008, 1692, 75
3008, 1692, 120
3008, 1692, 144
3008, 1692, 240
3200, 1800, 60
3200, 1800, 75
3200, 1800, 120
3200, 1800, 144
3200, 1800, 240
3200, 2400, 60
3200, 2400, 75
3200, 2400, 120
3200, 2400, 144
3200, 2400, 240
3840, 2160, 60
3840, 2160, 75
3840, 2160, 120
3840, 2160, 144
3840, 2160, 240
3840, 2400, 60
3840, 2400, 75
3840, 2400, 120
3840, 2400, 144
3840, 2400, 240
4096, 2304, 60
4096, 2304, 75
4096, 2304, 120
4096, 2304, 144
4096, 2304, 240
4096, 2560, 60
4096, 2560, 75
4096, 2560, 120
4096, 2560, 144
4096, 2560, 240
5120, 2880, 60
5120, 2880, 75
5120, 2880, 120
5120, 2880, 144
5120, 2880, 240
6016, 3384, 60
6016, 3384, 75
6016, 3384, 120
6016, 3384, 144
6016, 3384, 240
7680, 4320, 60
7680, 4320, 75
7680, 4320, 120
7680, 4320, 144
7680, 4320, 240
640, 480, 30
640, 480, 500
800, 5000, 500
1024, 768, 500
1152, 864, 500
1280, 5000, 500
1280, 720, 500
1280, 768, 500
1280, 800, 500
1280, 960, 500
1280, 1024, 500
1360, 768, 500
1366, 768, 500
1400, 1050, 500
1440, 900, 500
1600, 900, 500
1680, 1050, 500
1600, 1024, 500
1920, 1080, 500
1920, 1200, 500
1920, 1440, 500
2560, 1440, 500
2560, 1600, 500
2732, 2048, 500
2880, 1620, 500
2880, 1800, 500
3008, 1692, 500
3200, 1800, 500
3200, 2400, 500
3840, 2160, 500
3840, 2400, 500
4096, 2304, 500
4096, 2560, 500
5120, 2880, 500
6016, 3384, 500
7680, 4320, 500
2560, 1080, 500
2880, 1200, 500
3440, 1440, 500
3840, 1600, 500
4320, 1800, 500
5120, 2160, 500
5760, 2400, 500
6880, 2880, 500
7680, 3200, 500
8640, 3600, 500
10240, 432, 500
2880, 900, 500
3840, 1080, 500
3840, 1200, 500
4320, 1200, 500
5120, 1440, 500
5120, 1600, 500
5760, 1600, 500
5760, 1800, 500
6400, 1800, 500
6480, 1800, 500
7680, 2160, 500
7680, 2400, 500
8640, 2400, 500
2388, 1668, 500
2400, 1080, 500
3456, 2234, 500
8640, 3600, 30
8640, 3600, 60
8640, 3600, 75
8640, 3600, 90
8640, 3600, 120
8640, 3600, 144
8640, 3600, 165
8640, 3600, 240
8640, 3600, 480
+20
View File
@@ -0,0 +1,20 @@
# Self-elevate the script if required
if (-Not ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] 'Administrator')) {
if ([int](Get-CimInstance -Class Win32_OperatingSystem | Select-Object -ExpandProperty BuildNumber) -ge 6000) {
$CommandLine = "-File `"" + $MyInvocation.MyCommand.Path + "`" " + $MyInvocation.UnboundArguments
Start-Process -FilePath PowerShell.exe -Verb Runas -ArgumentList $CommandLine
Exit
}
}
$device = get-pnpdevice -class Display -FriendlyName 'IddSampleDriver Device HDR' -ErrorAction SilentlyContinue
if ($device) {
if ($device.Status -eq 'OK') {
Write-Host "Disabling device"; $device | disable-pnpdevice -Confirm:$false
} else {
Write-Host "Enabling device"; $device | enable-pnpdevice -Confirm:$false
}
} else {
Write-Warning "Device not found"
}