Updated for DirectX Tool Kit February 2017 releases

This commit is contained in:
Chuck Walbourn 2017-02-15 13:24:21 -08:00
Родитель c8776e23a2
Коммит 46a3295b50
21 изменённых файлов: 631 добавлений и 188 удалений

Просмотреть файл

@ -639,4 +639,9 @@
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
<Target Name="ATGEnsureShaders" BeforeTargets="PrepareForBuild">
<Exec Condition="!Exists('src/Shaders/Compiled/SpriteEffect_SpriteVertexShader.inc')"
WorkingDirectory="$(ProjectDir)src/Shaders"
Command="CompileShaders" />
</Target>
</Project>

Просмотреть файл

@ -404,7 +404,7 @@ namespace DirectX
bool __cdecl IsKeyDown(Keys key) const
{
if (key >= 0 && key <= 0xff)
if (key >= 0 && key <= 0xfe)
{
auto ptr = reinterpret_cast<const uint32_t*>(this);
unsigned int bf = 1u << (key & 0x1f);

Просмотреть файл

@ -4,7 +4,7 @@ DirectXTK - the DirectX Tool Kit for DirectX 11
Copyright (c) Microsoft Corporation. All rights reserved.
December 5, 2016
February 10, 2017
This package contains the "DirectX Tool Kit", a collection of helper classes for
writing Direct3D 11 C++ code for Universal Windows Platform (UWP) apps for Windows 10,
@ -79,6 +79,12 @@ https://opensource.microsoft.com/codeofconduct/
RELEASE HISTORY
---------------
February 10, 2017
GamePad now supports special value of -1 for 'most recently connected controller'
WIC format 40bppCMYKAlpha should be converted to RGBA8 rather than RGBA16
DDS support for L8A8 with bitcount 8 rather than 16
Minor code cleanup
December 5, 2016
Mouse and Keyboard classes updated with IsConnected method
Windows10 project /ZW switch removed to support use in C++/WinRT projection apps

Просмотреть файл

@ -90,7 +90,8 @@ public:
Impl(GamePad* owner) :
mOwner(owner),
mCtrlChanged(INVALID_HANDLE_VALUE),
mUserChanged(INVALID_HANDLE_VALUE)
mUserChanged(INVALID_HANDLE_VALUE),
mMostRecentGamepad(0)
{
using namespace Microsoft::WRL;
using namespace Microsoft::WRL::Wrappers;
@ -169,6 +170,9 @@ public:
ScanGamePads();
}
if (player == -1)
player = mMostRecentGamepad;
if ( ( player >= 0 ) && ( player < MAX_PLAYER_COUNT ) )
{
if ( mGamePad[ player ] )
@ -201,11 +205,11 @@ public:
ApplyStickDeadZone( static_cast<float>(reading.LeftThumbstickX), static_cast<float>(reading.LeftThumbstickY),
deadZoneMode, 1.f, .24f /* Recommended Xbox One deadzone */,
static_cast<float>(state.thumbSticks.leftX), static_cast<float>(state.thumbSticks.leftY) );
state.thumbSticks.leftX, state.thumbSticks.leftY );
ApplyStickDeadZone( static_cast<float>(reading.RightThumbstickX), static_cast<float>(reading.RightThumbstickY),
deadZoneMode, 1.f, .24f /* Recommended Xbox One deadzone */,
static_cast<float>(state.thumbSticks.rightX), static_cast<float>(state.thumbSticks.rightY) );
state.thumbSticks.rightX, state.thumbSticks.rightY );
state.triggers.left = static_cast<float>(reading.LeftTrigger);
state.triggers.right = static_cast<float>(reading.RightTrigger);
@ -229,6 +233,9 @@ public:
ScanGamePads();
}
if (player == -1)
player = mMostRecentGamepad;
if ( ( player >= 0 ) && ( player < MAX_PLAYER_COUNT ) )
{
if ( mGamePad[ player ] )
@ -265,6 +272,9 @@ public:
{
using namespace ABI::Windows::Gaming::Input;
if (player == -1)
player = mMostRecentGamepad;
if ( ( player >= 0 ) && ( player < MAX_PLAYER_COUNT ) )
{
if ( mGamePad[ player ] )
@ -306,6 +316,8 @@ public:
HANDLE mUserChanged;
private:
int mMostRecentGamepad;
void ScanGamePads()
{
using namespace Microsoft::WRL;
@ -362,6 +374,8 @@ private:
{
if ( mGamePad[ k ] == pad )
{
if (j == (count - 1))
mMostRecentGamepad = static_cast<int>(k);
break;
}
else if ( !mGamePad[ k ] )
@ -377,6 +391,8 @@ private:
if ( empty < MAX_PLAYER_COUNT )
{
mGamePad[ empty ] = pad;
if (j == (count - 1))
mMostRecentGamepad = static_cast<int>(empty);
ComPtr<IGameController> ctrl;
hr = pad.As(&ctrl);
@ -526,7 +542,8 @@ public:
Impl(GamePad *owner) :
mOwner(owner),
mCtrlChanged(INVALID_HANDLE_VALUE),
mUserChanged(INVALID_HANDLE_VALUE)
mUserChanged(INVALID_HANDLE_VALUE),
mMostRecentGamepad(0)
{
using namespace Microsoft::WRL;
using namespace Microsoft::WRL::Wrappers;
@ -596,6 +613,9 @@ public:
ScanGamePads();
}
if (player == -1)
player = mMostRecentGamepad;
if ( ( player >= 0 ) && ( player < MAX_PLAYER_COUNT ) )
{
if ( mGamePad[ player ] )
@ -655,6 +675,9 @@ public:
ScanGamePads();
}
if (player == -1)
player = mMostRecentGamepad;
if ( ( player >= 0 ) && ( player < MAX_PLAYER_COUNT ) )
{
if ( mGamePad[ player ] )
@ -703,6 +726,9 @@ public:
{
using namespace ABI::Windows::Xbox::Input;
if (player == -1)
player = mMostRecentGamepad;
if ( ( player >= 0 ) && ( player < MAX_PLAYER_COUNT ) )
{
if ( mGamePad[ player ] )
@ -753,6 +779,8 @@ public:
HANDLE mUserChanged;
private:
int mMostRecentGamepad;
void ScanGamePads()
{
using namespace ABI::Windows::Foundation::Collections;
@ -800,6 +828,8 @@ private:
{
if ( mGamePad[ k ] == pad )
{
if (!j)
mMostRecentGamepad = static_cast<int>(k);
break;
}
else if ( !mGamePad[ k ] )
@ -817,6 +847,8 @@ private:
}
mGamePad[ empty ] = pad;
if (!j)
mMostRecentGamepad = static_cast<int>(empty);
}
}
}
@ -941,7 +973,12 @@ public:
void GetState( int player, _Out_ State& state, DeadZone deadZoneMode )
{
if ( !ThrottleRetry(player) )
if (player == -1)
player = GetMostRecent();
ULONGLONG time = GetTickCount64();
if ( !ThrottleRetry(player, time) )
{
#if (_WIN32_WINNT < _WIN32_WINNT_WIN8)
if ( mSuspended )
@ -956,10 +993,13 @@ public:
DWORD result = XInputGetState( DWORD(player), &xstate );
if ( result == ERROR_DEVICE_NOT_CONNECTED )
{
ClearSlot( player, GetTickCount64() );
ClearSlot( player, time );
}
else
{
if (!mConnected[player])
mLastReadTime[player] = time;
mConnected[ player ] = true;
state.connected = true;
@ -1010,16 +1050,24 @@ public:
void GetCapabilities( int player, _Out_ Capabilities& caps )
{
if ( !ThrottleRetry(player) )
if (player == -1)
player = GetMostRecent();
ULONGLONG time = GetTickCount64();
if ( !ThrottleRetry(player, time) )
{
XINPUT_CAPABILITIES xcaps;
DWORD result = XInputGetCapabilities( DWORD(player), 0, &xcaps );
if ( result == ERROR_DEVICE_NOT_CONNECTED )
{
ClearSlot( player, GetTickCount64() );
ClearSlot( player, time );
}
else
{
if (!mConnected[player])
mLastReadTime[player] = time;
mConnected[ player ] = true;
caps.connected = true;
@ -1051,7 +1099,12 @@ public:
bool SetVibration( int player, float leftMotor, float rightMotor, float leftTrigger, float rightTrigger )
{
if ( ThrottleRetry(player) )
if (player == -1)
player = GetMostRecent();
ULONGLONG time = GetTickCount64();
if ( ThrottleRetry(player, time) )
{
return false;
}
@ -1075,11 +1128,14 @@ public:
DWORD result = XInputSetState( DWORD(player), &xvibration );
if ( result == ERROR_DEVICE_NOT_CONNECTED )
{
ClearSlot( player, GetTickCount64() );
ClearSlot( player, time );
return false;
}
else
{
if (!mConnected[player])
mLastReadTime[player] = time;
mConnected[ player ] = true;
return (result == ERROR_SUCCESS);
}
@ -1116,6 +1172,8 @@ public:
// For XInput 9.1.0, we have to emulate the behavior of XInputEnable( TRUE )
if ( mSuspended )
{
ULONGLONG time = GetTickCount64();
for( int j = 0; j < XUSER_MAX_COUNT; ++j )
{
if ( mConnected[ j ] )
@ -1126,7 +1184,7 @@ public:
DWORD result = XInputSetState( DWORD(j), &xvibration );
if ( result == ERROR_DEVICE_NOT_CONNECTED )
{
ClearSlot( j, GetTickCount64() );
ClearSlot( j, time );
}
}
}
@ -1151,7 +1209,7 @@ private:
bool mSuspended;
#endif
bool ThrottleRetry( int player )
bool ThrottleRetry( int player, ULONGLONG time )
{
// This function minimizes a potential performance issue with XInput on Windows when
// checking a disconnected controller slot which requires device enumeration.
@ -1163,8 +1221,6 @@ private:
if ( mConnected[ player ] )
return false;
ULONGLONG time = GetTickCount64();
for( size_t j = 0; j < XUSER_MAX_COUNT; ++j )
{
if ( !mConnected[j] )
@ -1191,6 +1247,23 @@ private:
mLeftMotor[ player ] = mRightMotor[ player ] = 0.f;
#endif
}
int GetMostRecent()
{
int player = -1;
ULONGLONG time = 0;
for (size_t j = 0; j < XUSER_MAX_COUNT; ++j)
{
if (mConnected[j] && (mLastReadTime[j] > time))
{
time = mLastReadTime[j];
player = static_cast<int>(j);
}
}
return player;
}
};
GamePad::Impl* GamePad::Impl::s_gamePad = nullptr;

Просмотреть файл

@ -635,6 +635,11 @@ namespace DirectX
}
// No DXGI format maps to ISBITMASK(0x0f,0x00,0x00,0xf0) aka D3DFMT_A4L4
if (ISBITMASK(0x000000ff, 0x00000000, 0x00000000, 0x0000ff00))
{
return DXGI_FORMAT_R8G8_UNORM; // Some DDS writers assume the bitcount should be 8 instead of 16
}
}
if (16 == ddpf.RGBBitCount)

Просмотреть файл

@ -431,7 +431,7 @@ HRESULT DirectX::SaveWICTextureToFile( ID3D11DeviceContext* pContext,
{
// Opt-in to the WIC2 support for writing 32-bit Windows BMP files with an alpha channel
PROPBAG2 option = {};
option.pstrName = L"EnableV5Header32bppBGRA";
option.pstrName = const_cast<wchar_t*>(L"EnableV5Header32bppBGRA");
VARIANT varValue;
varValue.vt = VT_BOOL;
@ -517,7 +517,7 @@ HRESULT DirectX::SaveWICTextureToFile( ID3D11DeviceContext* pContext,
PropVariantInit( &value );
value.vt = VT_LPSTR;
value.pszVal = "DirectXTK";
value.pszVal = const_cast<char*>("DirectXTK");
if ( memcmp( &guidContainerFormat, &GUID_ContainerFormatPng, sizeof(GUID) ) == 0 )
{

Просмотреть файл

@ -130,9 +130,9 @@ namespace
{ GUID_WICPixelFormat128bppRGBFixedPoint, GUID_WICPixelFormat128bppRGBAFloat }, // DXGI_FORMAT_R32G32B32A32_FLOAT
{ GUID_WICPixelFormat32bppRGBE, GUID_WICPixelFormat128bppRGBAFloat }, // DXGI_FORMAT_R32G32B32A32_FLOAT
{ GUID_WICPixelFormat32bppCMYK, GUID_WICPixelFormat32bppRGBA }, // DXGI_FORMAT_R8G8B8A8_UNORM
{ GUID_WICPixelFormat32bppCMYK, GUID_WICPixelFormat32bppRGBA }, // DXGI_FORMAT_R8G8B8A8_UNORM
{ GUID_WICPixelFormat64bppCMYK, GUID_WICPixelFormat64bppRGBA }, // DXGI_FORMAT_R16G16B16A16_UNORM
{ GUID_WICPixelFormat40bppCMYKAlpha, GUID_WICPixelFormat64bppRGBA }, // DXGI_FORMAT_R16G16B16A16_UNORM
{ GUID_WICPixelFormat40bppCMYKAlpha, GUID_WICPixelFormat32bppRGBA }, // DXGI_FORMAT_R8G8B8A8_UNORM
{ GUID_WICPixelFormat80bppCMYKAlpha, GUID_WICPixelFormat64bppRGBA }, // DXGI_FORMAT_R16G16B16A16_UNORM
#if (_WIN32_WINNT >= _WIN32_WINNT_WIN8) || defined(_WIN7_PLATFORM_UPDATE)
@ -318,12 +318,12 @@ namespace
if (width > height)
{
twidth = static_cast<UINT>(maxsize);
theight = static_cast<UINT>(static_cast<float>(maxsize) * ar);
theight = std::max<UINT>(1, static_cast<UINT>(static_cast<float>(maxsize) * ar));
}
else
{
theight = static_cast<UINT>(maxsize);
twidth = static_cast<UINT>(static_cast<float>(maxsize) / ar);
twidth = std::max<UINT>(1, static_cast<UINT>(static_cast<float>(maxsize) / ar));
}
assert(twidth <= maxsize && theight <= maxsize);
}
@ -354,12 +354,14 @@ namespace
{
memcpy(&convertGUID, &GUID_WICPixelFormat96bppRGBFloat, sizeof(WICPixelFormatGUID));
format = DXGI_FORMAT_R32G32B32_FLOAT;
bpp = 96;
}
else
#endif
{
memcpy(&convertGUID, &GUID_WICPixelFormat128bppRGBAFloat, sizeof(WICPixelFormatGUID));
format = DXGI_FORMAT_R32G32B32A32_FLOAT;
bpp = 128;
}
}
else

Просмотреть файл

@ -571,4 +571,9 @@
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
<Target Name="ATGEnsureShaders" BeforeTargets="PrepareForBuild">
<Exec Condition="!Exists('src/Shaders/Compiled/SpriteEffect_SpriteVertexShader.inc')"
WorkingDirectory="$(ProjectDir)src/Shaders"
Command="CompileShaders" />
</Target>
</Project>

Просмотреть файл

@ -404,7 +404,7 @@ namespace DirectX
bool __cdecl IsKeyDown(Keys key) const
{
if (key >= 0 && key <= 0xff)
if (key >= 0 && key <= 0xfe)
{
auto ptr = reinterpret_cast<const uint32_t*>(this);
unsigned int bf = 1u << (key & 0x1f);

Просмотреть файл

@ -28,27 +28,27 @@ namespace DirectX
class RenderTargetState
{
public:
RenderTargetState::RenderTargetState()
: sampleDesc{}
, rtvFormats{}
, sampleMask(~0U)
RenderTargetState()
: sampleMask(~0U)
, numRenderTargets(0)
, rtvFormats{}
, dsvFormat(DXGI_FORMAT_UNKNOWN)
, sampleDesc{}
, nodeMask(0)
{
}
RenderTargetState::RenderTargetState(const RenderTargetState& o) = default;
RenderTargetState(const RenderTargetState&) = default;
// Single render target convenience constructor
RenderTargetState::RenderTargetState(
RenderTargetState(
_In_ DXGI_FORMAT rtFormat,
_In_ DXGI_FORMAT dsFormat)
: sampleMask(UINT_MAX)
, sampleDesc{}
, rtvFormats{}
, numRenderTargets(1)
, rtvFormats{}
, dsvFormat(dsFormat)
, sampleDesc{}
, nodeMask(0)
{
sampleDesc.Count = 1;
@ -56,14 +56,14 @@ namespace DirectX
}
// Convenience constructor converting from DXGI_SWAPCHAIN_DESC
RenderTargetState::RenderTargetState(
RenderTargetState(
_In_ const DXGI_SWAP_CHAIN_DESC* desc,
_In_ DXGI_FORMAT dsFormat)
: sampleMask(UINT_MAX)
, sampleDesc{}
, rtvFormats{}
, numRenderTargets(1)
, rtvFormats{}
, dsvFormat(dsFormat)
, sampleDesc{}
, nodeMask(0)
{
rtvFormats[0] = desc->BufferDesc.Format;

Просмотреть файл

@ -4,7 +4,7 @@ DirectXTK - the DirectX Tool Kit for DirectX 12
Copyright (c) Microsoft Corporation. All rights reserved.
December 5, 2016
February 10, 2017
This package contains the "DirectX Tool Kit", a collection of helper classes for
writing Direct3D 12 C++ code for Universal Windows Platform (UWP) apps, Win32 desktop
@ -95,6 +95,15 @@ COMPARISONS TO DIRECTX 11 VERSION
RELEASE HISTORY
---------------
February 10, 2017
SpriteBatch default rasterizer state now matches DirectX 11 version
DDSTextureLoader now supports loading planar video format textures
GamePad now supports special value of -1 for 'most recently connected controller'
WIC format 40bppCMYKAlpha should be converted to RGBA8 rather than RGBA16
DDS support for L8A8 with bitcount 8 rather than 16
Updated D3DX12 internal copy to latest version
Minor code cleanup
December 5, 2016
Mouse and Keyboard classes updated with IsConnected method
Windows10 project /ZW switch removed to support use in C++/WinRT projection apps

Просмотреть файл

@ -112,7 +112,7 @@ const D3D12_DEPTH_STENCIL_DESC CommonStates::DepthNone =
D3D12_STENCIL_OP_KEEP, // StencilDepthFailOp
D3D12_STENCIL_OP_KEEP, // StencilPassOp
D3D12_COMPARISON_FUNC_ALWAYS // StencilFunc
}, // FrontFace,
}, // FrontFace
{
D3D12_STENCIL_OP_KEEP, // StencilFailOp
D3D12_STENCIL_OP_KEEP, // StencilDepthFailOp
@ -134,7 +134,7 @@ const D3D12_DEPTH_STENCIL_DESC CommonStates::DepthDefault =
D3D12_STENCIL_OP_KEEP, // StencilDepthFailOp
D3D12_STENCIL_OP_KEEP, // StencilPassOp
D3D12_COMPARISON_FUNC_ALWAYS // StencilFunc
}, // FrontFace,
}, // FrontFace
{
D3D12_STENCIL_OP_KEEP, // StencilFailOp
D3D12_STENCIL_OP_KEEP, // StencilDepthFailOp
@ -156,7 +156,7 @@ const D3D12_DEPTH_STENCIL_DESC CommonStates::DepthRead =
D3D12_STENCIL_OP_KEEP, // StencilDepthFailOp
D3D12_STENCIL_OP_KEEP, // StencilPassOp
D3D12_COMPARISON_FUNC_ALWAYS // StencilFunc
}, // FrontFace,
}, // FrontFace
{
D3D12_STENCIL_OP_KEEP, // StencilFailOp
D3D12_STENCIL_OP_KEEP, // StencilDepthFailOp

Просмотреть файл

@ -41,6 +41,80 @@ static_assert(DDS_DIMENSION_TEXTURE3D == D3D12_RESOURCE_DIMENSION_TEXTURE3D, "dd
namespace
{
inline bool IsDepthStencil(DXGI_FORMAT fmt)
{
switch (fmt)
{
case DXGI_FORMAT_R32G8X24_TYPELESS:
case DXGI_FORMAT_D32_FLOAT_S8X24_UINT:
case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS:
case DXGI_FORMAT_X32_TYPELESS_G8X24_UINT:
case DXGI_FORMAT_D32_FLOAT:
case DXGI_FORMAT_R24G8_TYPELESS:
case DXGI_FORMAT_D24_UNORM_S8_UINT:
case DXGI_FORMAT_R24_UNORM_X8_TYPELESS:
case DXGI_FORMAT_X24_TYPELESS_G8_UINT:
case DXGI_FORMAT_D16_UNORM:
#if defined(_XBOX_ONE) && defined(_TITLE)
case DXGI_FORMAT_D16_UNORM_S8_UINT:
case DXGI_FORMAT_R16_UNORM_X8_TYPELESS:
case DXGI_FORMAT_X16_TYPELESS_G8_UINT:
#endif
return true;
default:
return false;
}
}
//--------------------------------------------------------------------------------------
inline void AdjustPlaneResource(
_In_ DXGI_FORMAT fmt,
_In_ size_t height,
_In_ size_t slicePlane,
_Inout_ D3D12_SUBRESOURCE_DATA& res)
{
switch (fmt)
{
case DXGI_FORMAT_NV12:
case DXGI_FORMAT_P010:
case DXGI_FORMAT_P016:
#if defined(_XBOX_ONE) && defined(_TITLE)
case DXGI_FORMAT_D16_UNORM_S8_UINT:
case DXGI_FORMAT_R16_UNORM_X8_TYPELESS:
case DXGI_FORMAT_X16_TYPELESS_G8_UINT:
#endif
if (!slicePlane)
{
// Plane 0
res.SlicePitch = res.RowPitch * height;
}
else
{
// Plane 1
res.pData = reinterpret_cast<const uint8_t*>(res.pData) + res.RowPitch * height;
res.SlicePitch = res.RowPitch * ((height + 1) >> 1);
}
break;
case DXGI_FORMAT_NV11:
if (!slicePlane)
{
// Plane 0
res.SlicePitch = res.RowPitch * height;
}
else
{
// Plane 1
res.pData = reinterpret_cast<const uint8_t*>(res.pData) + res.RowPitch * height;
res.RowPitch = (res.RowPitch >> 1);
res.SlicePitch = res.RowPitch * height;
}
break;
}
}
//--------------------------------------------------------------------------------------
HRESULT FillInitData(_In_ size_t width,
@ -48,6 +122,7 @@ namespace
_In_ size_t depth,
_In_ size_t mipCount,
_In_ size_t arraySize,
_In_ size_t numberOfPlanes,
_In_ DXGI_FORMAT format,
_In_ size_t maxsize,
_In_ size_t bitSize,
@ -56,9 +131,9 @@ namespace
_Out_ size_t& theight,
_Out_ size_t& tdepth,
_Out_ size_t& skipMip,
_Out_writes_(mipCount*arraySize) D3D12_SUBRESOURCE_DATA* initData)
std::vector<D3D12_SUBRESOURCE_DATA>& initData)
{
if (!bitData || !initData)
if (!bitData)
{
return E_POINTER;
}
@ -70,73 +145,82 @@ namespace
size_t NumBytes = 0;
size_t RowBytes = 0;
const uint8_t* pSrcBits = bitData;
const uint8_t* pEndBits = bitData + bitSize;
size_t index = 0;
for (size_t j = 0; j < arraySize; j++)
{
size_t w = width;
size_t h = height;
size_t d = depth;
for (size_t i = 0; i < mipCount; i++)
{
GetSurfaceInfo(w,
h,
format,
&NumBytes,
&RowBytes,
nullptr
);
initData.clear();
if ((mipCount <= 1) || !maxsize || (w <= maxsize && h <= maxsize && d <= maxsize))
for (size_t p = 0; p < numberOfPlanes; ++p)
{
const uint8_t* pSrcBits = bitData;
for (size_t j = 0; j < arraySize; j++)
{
size_t w = width;
size_t h = height;
size_t d = depth;
for (size_t i = 0; i < mipCount; i++)
{
if (!twidth)
GetSurfaceInfo(w,
h,
format,
&NumBytes,
&RowBytes,
nullptr
);
if ((mipCount <= 1) || !maxsize || (w <= maxsize && h <= maxsize && d <= maxsize))
{
twidth = w;
theight = h;
tdepth = d;
if (!twidth)
{
twidth = w;
theight = h;
tdepth = d;
}
D3D12_SUBRESOURCE_DATA res =
{
reinterpret_cast<const void*>(pSrcBits),
static_cast<LONG_PTR>(RowBytes),
static_cast<LONG_PTR>(NumBytes)
};
AdjustPlaneResource(format, h, p, res);
initData.emplace_back(res);
}
else if (!j)
{
// Count number of skipped mipmaps (first item only)
++skipMip;
}
assert(index < mipCount * arraySize);
_Analysis_assume_(index < mipCount * arraySize);
initData[index].pData = reinterpret_cast<const void*>(pSrcBits);
initData[index].RowPitch = RowBytes;
initData[index].SlicePitch = NumBytes;
++index;
}
else if (!j)
{
// Count number of skipped mipmaps (first item only)
++skipMip;
}
if (pSrcBits + (NumBytes*d) > pEndBits)
{
return HRESULT_FROM_WIN32(ERROR_HANDLE_EOF);
}
if (pSrcBits + (NumBytes*d) > pEndBits)
{
return HRESULT_FROM_WIN32(ERROR_HANDLE_EOF);
}
pSrcBits += NumBytes * d;
pSrcBits += NumBytes * d;
w = w >> 1;
h = h >> 1;
d = d >> 1;
if (w == 0)
{
w = 1;
}
if (h == 0)
{
h = 1;
}
if (d == 0)
{
d = 1;
w = w >> 1;
h = h >> 1;
d = d >> 1;
if (w == 0)
{
w = 1;
}
if (h == 0)
{
h = 1;
}
if (d == 0)
{
d = 1;
}
}
}
}
return (index > 0) ? S_OK : E_FAIL;
return initData.empty() ? E_FAIL : S_OK;
}
//--------------------------------------------------------------------------------------
@ -373,21 +457,40 @@ namespace
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED);
}
UINT numberOfPlanes = D3D12GetFormatPlaneCount(d3dDevice, format);
if (!numberOfPlanes)
return E_INVALIDARG;
if ((numberOfPlanes > 1) && IsDepthStencil(format))
{
// DirectX 12 uses planes for stencil, DirectX 11 does not
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED);
}
if (outIsCubeMap != nullptr)
{
*outIsCubeMap = isCubeMap;
}
// Create the texture
std::vector<D3D12_SUBRESOURCE_DATA> initData;
initData.resize(mipCount * arraySize);
size_t numberOfResources = (resDim == D3D12_RESOURCE_DIMENSION_TEXTURE3D)
? 1 : arraySize;
numberOfResources *= mipCount;
numberOfResources *= numberOfPlanes;
if (numberOfResources > D3D12_REQ_SUBRESOURCES)
return E_INVALIDARG;
subresources.reserve(numberOfResources);
size_t skipMip = 0;
size_t twidth = 0;
size_t theight = 0;
size_t tdepth = 0;
hr = FillInitData(width, height, depth, mipCount, arraySize, format, maxsize, bitSize, bitData,
twidth, theight, tdepth, skipMip, &initData[0]);
hr = FillInitData(width, height, depth, mipCount, arraySize,
numberOfPlanes, format,
maxsize, bitSize, bitData,
twidth, theight, tdepth, skipMip, subresources);
if (SUCCEEDED(hr))
{
@ -402,12 +505,16 @@ namespace
if (FAILED(hr) && !maxsize && (mipCount > 1))
{
subresources.clear();
maxsize = (resDim == D3D12_RESOURCE_DIMENSION_TEXTURE3D)
? D3D12_REQ_TEXTURE3D_U_V_OR_W_DIMENSION
: D3D12_REQ_TEXTURE2D_U_OR_V_DIMENSION;
hr = FillInitData(width, height, depth, mipCount, arraySize, format, maxsize, bitSize, bitData,
twidth, theight, tdepth, skipMip, &initData[0]);
hr = FillInitData(width, height, depth, mipCount, arraySize,
numberOfPlanes, format,
maxsize, bitSize, bitData,
twidth, theight, tdepth, skipMip, subresources);
if (SUCCEEDED(hr))
{
hr = CreateTextureResource(d3dDevice, resDim, twidth, theight, tdepth, mipCount - skipMip, arraySize,
@ -416,9 +523,9 @@ namespace
}
}
if (SUCCEEDED(hr))
if (FAILED(hr))
{
subresources.insert(subresources.end(), initData.begin(), initData.end());
subresources.clear();
}
return hr;

Просмотреть файл

@ -32,7 +32,6 @@ void DirectX::CreateShaderResourceView(
switch (desc.Dimension)
{
case D3D12_RESOURCE_DIMENSION_TEXTURE1D:
{
if (desc.DepthOrArraySize > 1)
{
SRVDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE1DARRAY;
@ -44,19 +43,15 @@ void DirectX::CreateShaderResourceView(
SRVDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE1D;
SRVDesc.Texture1D.MipLevels = (!desc.MipLevels) ? -1 : desc.MipLevels;
}
}
break;
break;
case D3D12_RESOURCE_DIMENSION_TEXTURE2D:
{
if (isCubeMap)
{
if (desc.DepthOrArraySize > 6)
{
SRVDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURECUBEARRAY;
SRVDesc.TextureCubeArray.MipLevels = (!desc.MipLevels) ? -1 : desc.MipLevels;
// Earlier we set arraySize to (NumCubes * 6)
SRVDesc.TextureCubeArray.NumCubes = static_cast<UINT>(desc.DepthOrArraySize / 6);
}
else
@ -76,15 +71,12 @@ void DirectX::CreateShaderResourceView(
SRVDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D;
SRVDesc.Texture2D.MipLevels = (!desc.MipLevels) ? -1 : desc.MipLevels;
}
}
break;
break;
case D3D12_RESOURCE_DIMENSION_TEXTURE3D:
{
SRVDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE3D;
SRVDesc.Texture3D.MipLevels = (!desc.MipLevels) ? -1 : desc.MipLevels;
}
break;
break;
case D3D12_RESOURCE_DIMENSION_BUFFER:
throw std::exception("CreateShaderResourceView cannot be used with DIMENSION_BUFFER.");

Просмотреть файл

@ -90,7 +90,8 @@ public:
Impl(GamePad* owner) :
mOwner(owner),
mCtrlChanged(INVALID_HANDLE_VALUE),
mUserChanged(INVALID_HANDLE_VALUE)
mUserChanged(INVALID_HANDLE_VALUE),
mMostRecentGamepad(0)
{
using namespace Microsoft::WRL;
using namespace Microsoft::WRL::Wrappers;
@ -169,6 +170,9 @@ public:
ScanGamePads();
}
if (player == -1)
player = mMostRecentGamepad;
if ( ( player >= 0 ) && ( player < MAX_PLAYER_COUNT ) )
{
if ( mGamePad[ player ] )
@ -201,11 +205,11 @@ public:
ApplyStickDeadZone( static_cast<float>(reading.LeftThumbstickX), static_cast<float>(reading.LeftThumbstickY),
deadZoneMode, 1.f, .24f /* Recommended Xbox One deadzone */,
static_cast<float>(state.thumbSticks.leftX), static_cast<float>(state.thumbSticks.leftY) );
state.thumbSticks.leftX, state.thumbSticks.leftY );
ApplyStickDeadZone( static_cast<float>(reading.RightThumbstickX), static_cast<float>(reading.RightThumbstickY),
deadZoneMode, 1.f, .24f /* Recommended Xbox One deadzone */,
static_cast<float>(state.thumbSticks.rightX), static_cast<float>(state.thumbSticks.rightY) );
state.thumbSticks.rightX, state.thumbSticks.rightY );
state.triggers.left = static_cast<float>(reading.LeftTrigger);
state.triggers.right = static_cast<float>(reading.RightTrigger);
@ -229,6 +233,9 @@ public:
ScanGamePads();
}
if (player == -1)
player = mMostRecentGamepad;
if ( ( player >= 0 ) && ( player < MAX_PLAYER_COUNT ) )
{
if ( mGamePad[ player ] )
@ -265,6 +272,9 @@ public:
{
using namespace ABI::Windows::Gaming::Input;
if (player == -1)
player = mMostRecentGamepad;
if ( ( player >= 0 ) && ( player < MAX_PLAYER_COUNT ) )
{
if ( mGamePad[ player ] )
@ -306,6 +316,8 @@ public:
HANDLE mUserChanged;
private:
int mMostRecentGamepad;
void ScanGamePads()
{
using namespace Microsoft::WRL;
@ -362,6 +374,8 @@ private:
{
if ( mGamePad[ k ] == pad )
{
if (j == (count - 1))
mMostRecentGamepad = static_cast<int>(k);
break;
}
else if ( !mGamePad[ k ] )
@ -377,6 +391,8 @@ private:
if ( empty < MAX_PLAYER_COUNT )
{
mGamePad[ empty ] = pad;
if (j == (count - 1))
mMostRecentGamepad = static_cast<int>(empty);
ComPtr<IGameController> ctrl;
hr = pad.As(&ctrl);
@ -526,7 +542,8 @@ public:
Impl(GamePad *owner) :
mOwner(owner),
mCtrlChanged(INVALID_HANDLE_VALUE),
mUserChanged(INVALID_HANDLE_VALUE)
mUserChanged(INVALID_HANDLE_VALUE),
mMostRecentGamepad(0)
{
using namespace Microsoft::WRL;
using namespace Microsoft::WRL::Wrappers;
@ -596,6 +613,9 @@ public:
ScanGamePads();
}
if (player == -1)
player = mMostRecentGamepad;
if ( ( player >= 0 ) && ( player < MAX_PLAYER_COUNT ) )
{
if ( mGamePad[ player ] )
@ -655,6 +675,9 @@ public:
ScanGamePads();
}
if (player == -1)
player = mMostRecentGamepad;
if ( ( player >= 0 ) && ( player < MAX_PLAYER_COUNT ) )
{
if ( mGamePad[ player ] )
@ -703,6 +726,9 @@ public:
{
using namespace ABI::Windows::Xbox::Input;
if (player == -1)
player = mMostRecentGamepad;
if ( ( player >= 0 ) && ( player < MAX_PLAYER_COUNT ) )
{
if ( mGamePad[ player ] )
@ -753,6 +779,8 @@ public:
HANDLE mUserChanged;
private:
int mMostRecentGamepad;
void ScanGamePads()
{
using namespace ABI::Windows::Foundation::Collections;
@ -800,6 +828,8 @@ private:
{
if ( mGamePad[ k ] == pad )
{
if (!j)
mMostRecentGamepad = static_cast<int>(k);
break;
}
else if ( !mGamePad[ k ] )
@ -817,6 +847,8 @@ private:
}
mGamePad[ empty ] = pad;
if (!j)
mMostRecentGamepad = static_cast<int>(empty);
}
}
}
@ -941,7 +973,12 @@ public:
void GetState( int player, _Out_ State& state, DeadZone deadZoneMode )
{
if ( !ThrottleRetry(player) )
if (player == -1)
player = GetMostRecent();
ULONGLONG time = GetTickCount64();
if ( !ThrottleRetry(player, time) )
{
#if (_WIN32_WINNT < _WIN32_WINNT_WIN8)
if ( mSuspended )
@ -956,10 +993,13 @@ public:
DWORD result = XInputGetState( DWORD(player), &xstate );
if ( result == ERROR_DEVICE_NOT_CONNECTED )
{
ClearSlot( player, GetTickCount64() );
ClearSlot( player, time );
}
else
{
if (!mConnected[player])
mLastReadTime[player] = time;
mConnected[ player ] = true;
state.connected = true;
@ -1010,16 +1050,24 @@ public:
void GetCapabilities( int player, _Out_ Capabilities& caps )
{
if ( !ThrottleRetry(player) )
if (player == -1)
player = GetMostRecent();
ULONGLONG time = GetTickCount64();
if ( !ThrottleRetry(player, time) )
{
XINPUT_CAPABILITIES xcaps;
DWORD result = XInputGetCapabilities( DWORD(player), 0, &xcaps );
if ( result == ERROR_DEVICE_NOT_CONNECTED )
{
ClearSlot( player, GetTickCount64() );
ClearSlot( player, time );
}
else
{
if (!mConnected[player])
mLastReadTime[player] = time;
mConnected[ player ] = true;
caps.connected = true;
@ -1051,7 +1099,12 @@ public:
bool SetVibration( int player, float leftMotor, float rightMotor, float leftTrigger, float rightTrigger )
{
if ( ThrottleRetry(player) )
if (player == -1)
player = GetMostRecent();
ULONGLONG time = GetTickCount64();
if ( ThrottleRetry(player, time) )
{
return false;
}
@ -1075,11 +1128,14 @@ public:
DWORD result = XInputSetState( DWORD(player), &xvibration );
if ( result == ERROR_DEVICE_NOT_CONNECTED )
{
ClearSlot( player, GetTickCount64() );
ClearSlot( player, time );
return false;
}
else
{
if (!mConnected[player])
mLastReadTime[player] = time;
mConnected[ player ] = true;
return (result == ERROR_SUCCESS);
}
@ -1116,6 +1172,8 @@ public:
// For XInput 9.1.0, we have to emulate the behavior of XInputEnable( TRUE )
if ( mSuspended )
{
ULONGLONG time = GetTickCount64();
for( int j = 0; j < XUSER_MAX_COUNT; ++j )
{
if ( mConnected[ j ] )
@ -1126,7 +1184,7 @@ public:
DWORD result = XInputSetState( DWORD(j), &xvibration );
if ( result == ERROR_DEVICE_NOT_CONNECTED )
{
ClearSlot( j, GetTickCount64() );
ClearSlot( j, time );
}
}
}
@ -1151,7 +1209,7 @@ private:
bool mSuspended;
#endif
bool ThrottleRetry( int player )
bool ThrottleRetry( int player, ULONGLONG time )
{
// This function minimizes a potential performance issue with XInput on Windows when
// checking a disconnected controller slot which requires device enumeration.
@ -1163,8 +1221,6 @@ private:
if ( mConnected[ player ] )
return false;
ULONGLONG time = GetTickCount64();
for( size_t j = 0; j < XUSER_MAX_COUNT; ++j )
{
if ( !mConnected[j] )
@ -1191,6 +1247,23 @@ private:
mLeftMotor[ player ] = mRightMotor[ player ] = 0.f;
#endif
}
int GetMostRecent()
{
int player = -1;
ULONGLONG time = 0;
for (size_t j = 0; j < XUSER_MAX_COUNT; ++j)
{
if (mConnected[j] && (mLastReadTime[j] > time))
{
time = mLastReadTime[j];
player = static_cast<int>(j);
}
}
return player;
}
};
GamePad::Impl* GamePad::Impl::s_gamePad = nullptr;

Просмотреть файл

@ -635,6 +635,11 @@ namespace DirectX
}
// No DXGI format maps to ISBITMASK(0x0f,0x00,0x00,0xf0) aka D3DFMT_A4L4
if (ISBITMASK(0x000000ff, 0x00000000, 0x00000000, 0x0000ff00))
{
return DXGI_FORMAT_R8G8_UNORM; // Some DDS writers assume the bitcount should be 8 instead of 16
}
}
if (16 == ddpf.RGBBitCount)

Просмотреть файл

@ -74,7 +74,7 @@ namespace
}
}
bool FormatRequiresSwizzle(DXGI_FORMAT format)
bool FormatIsBGR(DXGI_FORMAT format)
{
switch (format)
{
@ -329,7 +329,7 @@ public:
{
throw std::exception("GenerateMips only supports 2D textures of array size 1");
}
if (!FormatIsUAVCompatible(desc.Format) && !FormatIsSRGB(desc.Format) && !FormatRequiresSwizzle(desc.Format))
if (!FormatIsUAVCompatible(desc.Format) && !FormatIsSRGB(desc.Format) && !FormatIsBGR(desc.Format))
{
throw std::exception("GenerateMips doesn't support this texture format");
}
@ -341,11 +341,15 @@ public:
}
// If the texture's format doesn't support UAVs we'll have to copy it to a texture that does first.
// This is true of BGRA (which need swizzling) or sRGB textures (which need de-gamma), for example.
// This is true of BGRA or sRGB textures, for example.
if (FormatIsUAVCompatible(desc.Format))
{
GenerateMips_UnorderedAccessPath(resource);
}
else if (FormatIsBGR(desc.Format))
{
GenerateMips_TexturePathBGR(resource);
}
else
{
GenerateMips_TexturePath(resource);
@ -430,8 +434,7 @@ private:
_In_ ID3D12Resource* resource)
{
const auto& desc = resource->GetDesc();
assert(!FormatRequiresSwizzle(desc.Format) && !FormatIsSRGB(desc.Format));
assert(!FormatIsBGR(desc.Format) && !FormatIsSRGB(desc.Format));
CD3DX12_HEAP_PROPERTIES defaultHeapProperties(D3D12_HEAP_TYPE_DEFAULT);
@ -604,7 +607,7 @@ private:
_In_ ID3D12Resource* resource)
{
const auto& resourceDesc = resource->GetDesc();
assert(FormatRequiresSwizzle(resourceDesc.Format) || FormatIsSRGB(resourceDesc.Format));
assert(!FormatIsBGR(resourceDesc.Format) || FormatIsSRGB(resourceDesc.Format));
auto copyDesc = resourceDesc;
copyDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
@ -643,6 +646,77 @@ private:
mTrackedObjects.push_back(resource);
}
// Resource is not UAV compatible (copy via alias to avoid validation failure)
void GenerateMips_TexturePathBGR(
_In_ ID3D12Resource* resource)
{
const auto& resourceDesc = resource->GetDesc();
assert(FormatIsBGR(resourceDesc.Format));
// Create a resource with the same description, but without SRGB, and with UAV flags
auto copyDesc = resourceDesc;
copyDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
copyDesc.Flags |= D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS;
D3D12_HEAP_DESC heapDesc = {};
auto allocInfo = mDevice->GetResourceAllocationInfo(0, 1, &resourceDesc);
heapDesc.SizeInBytes = allocInfo.SizeInBytes;
heapDesc.Flags = D3D12_HEAP_FLAG_ALLOW_ONLY_NON_RT_DS_TEXTURES;
heapDesc.Properties.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN;
heapDesc.Properties.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN;
heapDesc.Properties.Type = D3D12_HEAP_TYPE_DEFAULT;
ComPtr<ID3D12Heap> heap;
ThrowIfFailed(mDevice->CreateHeap(&heapDesc, IID_GRAPHICS_PPV_ARGS(heap.GetAddressOf())));
ComPtr<ID3D12Resource> resourceCopy;
ThrowIfFailed(mDevice->CreatePlacedResource(
heap.Get(),
0,
&copyDesc,
D3D12_RESOURCE_STATE_COPY_DEST,
nullptr,
IID_GRAPHICS_PPV_ARGS(resourceCopy.GetAddressOf())));
SetDebugObjectName(resourceCopy.Get(), L"GenerateMips Resource Copy");
// Create a BGRA alias
auto aliasDesc = resourceDesc;
aliasDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
ComPtr<ID3D12Resource> aliasCopy;
ThrowIfFailed(mDevice->CreatePlacedResource(
heap.Get(),
0,
&aliasDesc,
D3D12_RESOURCE_STATE_COPY_DEST,
nullptr,
IID_GRAPHICS_PPV_ARGS(aliasCopy.GetAddressOf())));
// Copy the resource data
AliasBarrier(nullptr, aliasCopy.Get());
Transition(resource, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE, D3D12_RESOURCE_STATE_COPY_SOURCE);
mList->CopyResource(aliasCopy.Get(), resource);
// Generate the mips
AliasBarrier(aliasCopy.Get(), resourceCopy.Get());
Transition(resourceCopy.Get(), D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE);
GenerateMips_UnorderedAccessPath(resourceCopy.Get());
// Direct copy back
AliasBarrier(resourceCopy.Get(), aliasCopy.Get());
Transition(aliasCopy.Get(), D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_COPY_SOURCE);
Transition(resource, D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_COPY_DEST);
mList->CopyResource(resource, aliasCopy.Get());
Transition(resource, D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE);
// Track these object lifetimes on the GPU
mTrackedObjects.push_back(heap);
mTrackedObjects.push_back(resourceCopy);
mTrackedObjects.push_back(aliasCopy);
mTrackedObjects.push_back(resource);
}
void AliasBarrier(_In_opt_ ID3D12Resource* before, _In_ ID3D12Resource* after)
{
if (before == after)

Просмотреть файл

@ -55,6 +55,10 @@ namespace
if (desc.Dimension != D3D12_RESOURCE_DIMENSION_TEXTURE2D)
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED);
UINT numberOfPlanes = D3D12GetFormatPlaneCount(device, desc.Format);
if (numberOfPlanes != 1)
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED);
D3D12_HEAP_PROPERTIES sourceHeapProperties;
D3D12_HEAP_FLAGS sourceHeapFlags;
HRESULT hr = pSource->GetHeapProperties(&sourceHeapProperties, &sourceHeapFlags);
@ -538,7 +542,7 @@ HRESULT DirectX::SaveWICTextureToFile(
{
// Opt-in to the WIC2 support for writing 32-bit Windows BMP files with an alpha channel
PROPBAG2 option = {};
option.pstrName = L"EnableV5Header32bppBGRA";
option.pstrName = const_cast<wchar_t*>(L"EnableV5Header32bppBGRA");
VARIANT varValue;
varValue.vt = VT_BOOL;
@ -615,7 +619,7 @@ HRESULT DirectX::SaveWICTextureToFile(
PropVariantInit(&value);
value.vt = VT_LPSTR;
value.pszVal = "DirectXTK";
value.pszVal = const_cast<char*>("DirectXTK");
if (memcmp(&guidContainerFormat, &GUID_ContainerFormatPng, sizeof(GUID)) == 0)
{

Просмотреть файл

@ -225,9 +225,63 @@ const D3D12_SHADER_BYTECODE SpriteBatch::Impl::s_DefaultPixelShaderByteCodeHeap
const D3D12_INPUT_LAYOUT_DESC SpriteBatch::Impl::s_DefaultInputLayoutDesc = VertexPositionColorTexture::InputLayout;
const D3D12_BLEND_DESC SpriteBatchPipelineStateDescription::s_DefaultBlendDesc = {FALSE, FALSE, {TRUE, FALSE, D3D12_BLEND_ONE, D3D12_BLEND_INV_SRC_ALPHA, D3D12_BLEND_OP_ADD, D3D12_BLEND_ONE, D3D12_BLEND_INV_SRC_ALPHA, D3D12_BLEND_OP_ADD, D3D12_LOGIC_OP_CLEAR, D3D12_COLOR_WRITE_ENABLE_ALL}};
const D3D12_RASTERIZER_DESC SpriteBatchPipelineStateDescription::s_DefaultRasterizerDesc = {D3D12_FILL_MODE_SOLID, D3D12_CULL_MODE_NONE, FALSE, 0, 0, 0, FALSE, FALSE, FALSE, 0, D3D12_CONSERVATIVE_RASTERIZATION_MODE_OFF};
const D3D12_DEPTH_STENCIL_DESC SpriteBatchPipelineStateDescription::s_DefaultDepthStencilDesc = {FALSE, D3D12_DEPTH_WRITE_MASK_ALL, D3D12_COMPARISON_FUNC_ALWAYS, FALSE, 0, 0};
// Matches CommonStates::AlphaBlend
const D3D12_BLEND_DESC SpriteBatchPipelineStateDescription::s_DefaultBlendDesc =
{
FALSE, // AlphaToCoverageEnable
FALSE, // IndependentBlendEnable
{
TRUE, // BlendEnable
FALSE, // LogicOpEnable
D3D12_BLEND_ONE, // SrcBlend
D3D12_BLEND_INV_SRC_ALPHA, // DestBlend
D3D12_BLEND_OP_ADD, // BlendOp
D3D12_BLEND_ONE, // SrcBlendAlpha
D3D12_BLEND_INV_SRC_ALPHA, // DestBlendAlpha
D3D12_BLEND_OP_ADD, // BlendOpAlpha
D3D12_LOGIC_OP_NOOP,
D3D12_COLOR_WRITE_ENABLE_ALL
}
};
// Same to CommonStates::CullCounterClockwise
const D3D12_RASTERIZER_DESC SpriteBatchPipelineStateDescription::s_DefaultRasterizerDesc =
{
D3D12_FILL_MODE_SOLID,
D3D12_CULL_MODE_BACK,
FALSE, // FrontCounterClockwise
D3D12_DEFAULT_DEPTH_BIAS,
D3D12_DEFAULT_DEPTH_BIAS_CLAMP,
D3D12_DEFAULT_SLOPE_SCALED_DEPTH_BIAS,
TRUE, // DepthClipEnable
TRUE, // MultisampleEnable
FALSE, // AntialiasedLineEnable
0, // ForcedSampleCount
D3D12_CONSERVATIVE_RASTERIZATION_MODE_OFF
};
// Same as CommonStates::DepthNone
const D3D12_DEPTH_STENCIL_DESC SpriteBatchPipelineStateDescription::s_DefaultDepthStencilDesc =
{
FALSE, // DepthEnable
D3D12_DEPTH_WRITE_MASK_ZERO,
D3D12_COMPARISON_FUNC_LESS_EQUAL, // DepthFunc
FALSE, // StencilEnable
D3D12_DEFAULT_STENCIL_READ_MASK,
D3D12_DEFAULT_STENCIL_WRITE_MASK,
{
D3D12_STENCIL_OP_KEEP, // StencilFailOp
D3D12_STENCIL_OP_KEEP, // StencilDepthFailOp
D3D12_STENCIL_OP_KEEP, // StencilPassOp
D3D12_COMPARISON_FUNC_ALWAYS // StencilFunc
}, // FrontFace
{
D3D12_STENCIL_OP_KEEP, // StencilFailOp
D3D12_STENCIL_OP_KEEP, // StencilDepthFailOp
D3D12_STENCIL_OP_KEEP, // StencilPassOp
D3D12_COMPARISON_FUNC_ALWAYS // StencilFunc
} // BackFace
};
// Per-device constructor.
SpriteBatch::Impl::DeviceResources::DeviceResources(_In_ ID3D12Device* device, ResourceUploadBatch& upload)
@ -284,6 +338,7 @@ void SpriteBatch::Impl::DeviceResources::CreateRootSignatures(_In_ ID3D12Device*
CD3DX12_DESCRIPTOR_RANGE textureSRV(D3D12_DESCRIPTOR_RANGE_TYPE_SRV, 1, 0);
{
// Same as CommonStates::StaticLinearClamp
CD3DX12_STATIC_SAMPLER_DESC sampler(
0, // register
D3D12_FILTER_MIN_MAG_MIP_LINEAR,
@ -354,7 +409,7 @@ SpriteBatch::Impl::Impl(ID3D12Device* device, ResourceUploadBatch& upload, const
mSampler{},
mTransformMatrix(MatrixIdentity),
mDeviceResources(deviceResourcesPool.DemandCreate(device, upload)),
mVertexPageSize(sizeof(VertexPositionNormalColorTexture) * MaxBatchSize * VerticesPerSprite),
mVertexPageSize(sizeof(VertexPositionColorTexture) * MaxBatchSize * VerticesPerSprite),
mVertexSegment {},
mSpriteCount(0)
{

Просмотреть файл

@ -135,9 +135,9 @@ namespace
{ GUID_WICPixelFormat128bppRGBFixedPoint, GUID_WICPixelFormat128bppRGBAFloat }, // DXGI_FORMAT_R32G32B32A32_FLOAT
{ GUID_WICPixelFormat32bppRGBE, GUID_WICPixelFormat128bppRGBAFloat }, // DXGI_FORMAT_R32G32B32A32_FLOAT
{ GUID_WICPixelFormat32bppCMYK, GUID_WICPixelFormat32bppRGBA }, // DXGI_FORMAT_R8G8B8A8_UNORM
{ GUID_WICPixelFormat32bppCMYK, GUID_WICPixelFormat32bppRGBA }, // DXGI_FORMAT_R8G8B8A8_UNORM
{ GUID_WICPixelFormat64bppCMYK, GUID_WICPixelFormat64bppRGBA }, // DXGI_FORMAT_R16G16B16A16_UNORM
{ GUID_WICPixelFormat40bppCMYKAlpha, GUID_WICPixelFormat64bppRGBA }, // DXGI_FORMAT_R16G16B16A16_UNORM
{ GUID_WICPixelFormat40bppCMYKAlpha, GUID_WICPixelFormat32bppRGBA }, // DXGI_FORMAT_R8G8B8A8_UNORM
{ GUID_WICPixelFormat80bppCMYKAlpha, GUID_WICPixelFormat64bppRGBA }, // DXGI_FORMAT_R16G16B16A16_UNORM
{ GUID_WICPixelFormat32bppRGB, GUID_WICPixelFormat32bppRGBA }, // DXGI_FORMAT_R8G8B8A8_UNORM
@ -248,12 +248,12 @@ namespace
if (width > height)
{
twidth = static_cast<UINT>(maxsize);
theight = static_cast<UINT>(static_cast<float>(maxsize) * ar);
theight = std::max<UINT>(1, static_cast<UINT>(static_cast<float>(maxsize) * ar));
}
else
{
theight = static_cast<UINT>(maxsize);
twidth = static_cast<UINT>(static_cast<float>(maxsize) / ar);
twidth = std::max<UINT>(1, static_cast<UINT>(static_cast<float>(maxsize) / ar));
}
assert(twidth <= maxsize && theight <= maxsize);
}

Просмотреть файл

@ -524,7 +524,7 @@ struct CD3DX12_SHADER_BYTECODE : public D3D12_SHADER_BYTECODE
BytecodeLength = pShaderBlob->GetBufferSize();
}
CD3DX12_SHADER_BYTECODE(
const void* _pShaderBytecode,
_In_reads_(bytecodeLength) const void* _pShaderBytecode,
SIZE_T bytecodeLength )
{
pShaderBytecode = _pShaderBytecode;
@ -1922,6 +1922,11 @@ inline HRESULT D3DX12SerializeVersionedRootSignature(
_Outptr_ ID3DBlob** ppBlob,
_Always_(_Outptr_opt_result_maybenull_) ID3DBlob** ppErrorBlob)
{
if (ppErrorBlob != NULL)
{
*ppErrorBlob = NULL;
}
switch (MaxVersion)
{
case D3D_ROOT_SIGNATURE_VERSION_1_0:
@ -1932,65 +1937,88 @@ inline HRESULT D3DX12SerializeVersionedRootSignature(
case D3D_ROOT_SIGNATURE_VERSION_1_1:
{
HRESULT hr = S_OK;
const D3D12_ROOT_SIGNATURE_DESC1& desc_1_1 = pRootSignatureDesc->Desc_1_1;
SIZE_T ParametersSize = sizeof(D3D12_ROOT_PARAMETER) * desc_1_1.NumParameters;
const SIZE_T ParametersSize = sizeof(D3D12_ROOT_PARAMETER) * desc_1_1.NumParameters;
void* pParameters = (ParametersSize > 0) ? HeapAlloc(GetProcessHeap(), 0, ParametersSize) : NULL;
if (ParametersSize > 0 && pParameters == NULL)
{
hr = E_OUTOFMEMORY;
}
D3D12_ROOT_PARAMETER* pParameters_1_0 = reinterpret_cast<D3D12_ROOT_PARAMETER*>(pParameters);
for (UINT n = 0; n < desc_1_1.NumParameters; n++)
if (SUCCEEDED(hr))
{
pParameters_1_0[n].ParameterType = desc_1_1.pParameters[n].ParameterType;
pParameters_1_0[n].ShaderVisibility = desc_1_1.pParameters[n].ShaderVisibility;
switch (desc_1_1.pParameters[n].ParameterType)
for (UINT n = 0; n < desc_1_1.NumParameters; n++)
{
case D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS:
pParameters_1_0[n].Constants.Num32BitValues = desc_1_1.pParameters[n].Constants.Num32BitValues;
pParameters_1_0[n].Constants.RegisterSpace = desc_1_1.pParameters[n].Constants.RegisterSpace;
pParameters_1_0[n].Constants.ShaderRegister = desc_1_1.pParameters[n].Constants.ShaderRegister;
break;
__analysis_assume(ParametersSize == sizeof(D3D12_ROOT_PARAMETER) * desc_1_1.NumParameters);
pParameters_1_0[n].ParameterType = desc_1_1.pParameters[n].ParameterType;
pParameters_1_0[n].ShaderVisibility = desc_1_1.pParameters[n].ShaderVisibility;
case D3D12_ROOT_PARAMETER_TYPE_CBV:
case D3D12_ROOT_PARAMETER_TYPE_SRV:
case D3D12_ROOT_PARAMETER_TYPE_UAV:
pParameters_1_0[n].Descriptor.RegisterSpace = desc_1_1.pParameters[n].Descriptor.RegisterSpace;
pParameters_1_0[n].Descriptor.ShaderRegister = desc_1_1.pParameters[n].Descriptor.ShaderRegister;
break;
case D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE:
const D3D12_ROOT_DESCRIPTOR_TABLE1& table_1_1 = desc_1_1.pParameters[n].DescriptorTable;
SIZE_T DescriptorRangesSize = sizeof(D3D12_DESCRIPTOR_RANGE) * table_1_1.NumDescriptorRanges;
void* pDescriptorRanges = (DescriptorRangesSize > 0) ? HeapAlloc(GetProcessHeap(), 0, DescriptorRangesSize) : NULL;
D3D12_DESCRIPTOR_RANGE* pDescriptorRanges_1_0 = reinterpret_cast<D3D12_DESCRIPTOR_RANGE*>(pDescriptorRanges);
for (UINT x = 0; x < table_1_1.NumDescriptorRanges; x++)
switch (desc_1_1.pParameters[n].ParameterType)
{
pDescriptorRanges_1_0[x].BaseShaderRegister = table_1_1.pDescriptorRanges[x].BaseShaderRegister;
pDescriptorRanges_1_0[x].NumDescriptors = table_1_1.pDescriptorRanges[x].NumDescriptors;
pDescriptorRanges_1_0[x].OffsetInDescriptorsFromTableStart = table_1_1.pDescriptorRanges[x].OffsetInDescriptorsFromTableStart;
pDescriptorRanges_1_0[x].RangeType = table_1_1.pDescriptorRanges[x].RangeType;
pDescriptorRanges_1_0[x].RegisterSpace = table_1_1.pDescriptorRanges[x].RegisterSpace;
case D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS:
pParameters_1_0[n].Constants.Num32BitValues = desc_1_1.pParameters[n].Constants.Num32BitValues;
pParameters_1_0[n].Constants.RegisterSpace = desc_1_1.pParameters[n].Constants.RegisterSpace;
pParameters_1_0[n].Constants.ShaderRegister = desc_1_1.pParameters[n].Constants.ShaderRegister;
break;
case D3D12_ROOT_PARAMETER_TYPE_CBV:
case D3D12_ROOT_PARAMETER_TYPE_SRV:
case D3D12_ROOT_PARAMETER_TYPE_UAV:
pParameters_1_0[n].Descriptor.RegisterSpace = desc_1_1.pParameters[n].Descriptor.RegisterSpace;
pParameters_1_0[n].Descriptor.ShaderRegister = desc_1_1.pParameters[n].Descriptor.ShaderRegister;
break;
case D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE:
const D3D12_ROOT_DESCRIPTOR_TABLE1& table_1_1 = desc_1_1.pParameters[n].DescriptorTable;
const SIZE_T DescriptorRangesSize = sizeof(D3D12_DESCRIPTOR_RANGE) * table_1_1.NumDescriptorRanges;
void* pDescriptorRanges = (DescriptorRangesSize > 0 && SUCCEEDED(hr)) ? HeapAlloc(GetProcessHeap(), 0, DescriptorRangesSize) : NULL;
if (DescriptorRangesSize > 0 && pDescriptorRanges == NULL)
{
hr = E_OUTOFMEMORY;
}
D3D12_DESCRIPTOR_RANGE* pDescriptorRanges_1_0 = reinterpret_cast<D3D12_DESCRIPTOR_RANGE*>(pDescriptorRanges);
if (SUCCEEDED(hr))
{
for (UINT x = 0; x < table_1_1.NumDescriptorRanges; x++)
{
__analysis_assume(DescriptorRangesSize == sizeof(D3D12_DESCRIPTOR_RANGE) * table_1_1.NumDescriptorRanges);
pDescriptorRanges_1_0[x].BaseShaderRegister = table_1_1.pDescriptorRanges[x].BaseShaderRegister;
pDescriptorRanges_1_0[x].NumDescriptors = table_1_1.pDescriptorRanges[x].NumDescriptors;
pDescriptorRanges_1_0[x].OffsetInDescriptorsFromTableStart = table_1_1.pDescriptorRanges[x].OffsetInDescriptorsFromTableStart;
pDescriptorRanges_1_0[x].RangeType = table_1_1.pDescriptorRanges[x].RangeType;
pDescriptorRanges_1_0[x].RegisterSpace = table_1_1.pDescriptorRanges[x].RegisterSpace;
}
}
D3D12_ROOT_DESCRIPTOR_TABLE& table_1_0 = pParameters_1_0[n].DescriptorTable;
table_1_0.NumDescriptorRanges = table_1_1.NumDescriptorRanges;
table_1_0.pDescriptorRanges = pDescriptorRanges_1_0;
}
D3D12_ROOT_DESCRIPTOR_TABLE& table_1_0 = pParameters_1_0[n].DescriptorTable;
table_1_0.NumDescriptorRanges = table_1_1.NumDescriptorRanges;
table_1_0.pDescriptorRanges = pDescriptorRanges_1_0;
}
}
CD3DX12_ROOT_SIGNATURE_DESC desc_1_0(desc_1_1.NumParameters, pParameters_1_0, desc_1_1.NumStaticSamplers, desc_1_1.pStaticSamplers, desc_1_1.Flags);
HRESULT hr = D3D12SerializeRootSignature(&desc_1_0, D3D_ROOT_SIGNATURE_VERSION_1, ppBlob, ppErrorBlob);
for (UINT n = 0; n < desc_1_0.NumParameters; n++)
if (SUCCEEDED(hr))
{
if (desc_1_0.pParameters[n].ParameterType == D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE)
{
HeapFree(GetProcessHeap(), 0, reinterpret_cast<void*>(const_cast<D3D12_DESCRIPTOR_RANGE*>(pParameters_1_0[n].DescriptorTable.pDescriptorRanges)));
}
CD3DX12_ROOT_SIGNATURE_DESC desc_1_0(desc_1_1.NumParameters, pParameters_1_0, desc_1_1.NumStaticSamplers, desc_1_1.pStaticSamplers, desc_1_1.Flags);
hr = D3D12SerializeRootSignature(&desc_1_0, D3D_ROOT_SIGNATURE_VERSION_1, ppBlob, ppErrorBlob);
}
if (pParameters)
{
for (UINT n = 0; n < desc_1_1.NumParameters; n++)
{
if (desc_1_1.pParameters[n].ParameterType == D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE)
{
HeapFree(GetProcessHeap(), 0, reinterpret_cast<void*>(const_cast<D3D12_DESCRIPTOR_RANGE*>(pParameters_1_0[n].DescriptorTable.pDescriptorRanges)));
}
}
HeapFree(GetProcessHeap(), 0, pParameters);
}
HeapFree(GetProcessHeap(), 0, pParameters);
return hr;
}
}