Merge remote-tracking branch 'origin/master' into sdl_platform
This commit is contained in:
@@ -11,6 +11,7 @@
|
||||
#include "GPUSamplerDX11.h"
|
||||
#include "GPUVertexLayoutDX11.h"
|
||||
#include "Engine/GraphicsDevice/DirectX/RenderToolsDX.h"
|
||||
#include "Engine/Graphics/PixelFormatExtensions.h"
|
||||
#include "Engine/Core/Math/Viewport.h"
|
||||
#include "Engine/Core/Math/Rectangle.h"
|
||||
#include "Engine/Profiler/RenderStats.h"
|
||||
@@ -216,7 +217,10 @@ void GPUContextDX11::ClearDepth(GPUTextureView* depthBuffer, float depthValue, u
|
||||
if (depthBufferDX11)
|
||||
{
|
||||
ASSERT(depthBufferDX11->DSV());
|
||||
_context->ClearDepthStencilView(depthBufferDX11->DSV(), D3D11_CLEAR_DEPTH, depthValue, stencilValue);
|
||||
UINT clearFlags = D3D11_CLEAR_DEPTH;
|
||||
if (PixelFormatExtensions::HasStencil(depthBufferDX11->GetFormat()))
|
||||
clearFlags |= D3D11_CLEAR_STENCIL;
|
||||
_context->ClearDepthStencilView(depthBufferDX11->DSV(), clearFlags, depthValue, stencilValue);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -150,6 +150,7 @@ void GPUTextureDX11::OnReleaseGPU()
|
||||
_handleArray.Release();
|
||||
_handleVolume.Release();
|
||||
_handleReadOnlyDepth.Release();
|
||||
_handleStencil.Release();
|
||||
DX_SAFE_RELEASE_CHECK(_resource, 0);
|
||||
|
||||
// Base
|
||||
@@ -547,6 +548,41 @@ void GPUTextureDX11::initHandles()
|
||||
}
|
||||
_handleReadOnlyDepth.Init(this, rtView, srView, dsView, nullptr, format, msaa);
|
||||
}
|
||||
|
||||
// Stencil view
|
||||
if (useDSV && useSRV && PixelFormatExtensions::HasStencil(format))
|
||||
{
|
||||
PixelFormat stencilFormat;
|
||||
switch (_dxgiFormatDSV)
|
||||
{
|
||||
case PixelFormat::D24_UNorm_S8_UInt:
|
||||
srDesc.Format = DXGI_FORMAT_X24_TYPELESS_G8_UINT;
|
||||
stencilFormat = PixelFormat::X24_Typeless_G8_UInt;
|
||||
break;
|
||||
case PixelFormat::D32_Float_S8X24_UInt:
|
||||
srDesc.Format = DXGI_FORMAT_X32_TYPELESS_G8X24_UINT;
|
||||
stencilFormat = PixelFormat::X32_Typeless_G8X24_UInt;
|
||||
break;
|
||||
}
|
||||
if (isCubeMap)
|
||||
{
|
||||
srDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE;
|
||||
srDesc.TextureCube.MostDetailedMip = 0;
|
||||
srDesc.TextureCube.MipLevels = mipLevels;
|
||||
}
|
||||
else if (isMsaa)
|
||||
{
|
||||
srDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DMS;
|
||||
}
|
||||
else
|
||||
{
|
||||
srDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
|
||||
srDesc.Texture2D.MostDetailedMip = 0;
|
||||
srDesc.Texture2D.MipLevels = mipLevels;
|
||||
}
|
||||
VALIDATE_DIRECTX_CALL(device->CreateShaderResourceView(_resource, &srDesc, &srView));
|
||||
_handleStencil.Init(this, nullptr, srView, nullptr, nullptr, stencilFormat, msaa);
|
||||
}
|
||||
}
|
||||
|
||||
bool GPUTextureDX11::GetData(int32 arrayIndex, int32 mipMapIndex, TextureMipData& data, uint32 mipRowPitch)
|
||||
|
||||
@@ -158,6 +158,7 @@ private:
|
||||
GPUTextureViewDX11 _handleArray;
|
||||
GPUTextureViewDX11 _handleVolume;
|
||||
GPUTextureViewDX11 _handleReadOnlyDepth;
|
||||
GPUTextureViewDX11 _handleStencil;
|
||||
Array<GPUTextureViewDX11> _handlesPerSlice; // [slice]
|
||||
Array<Array<GPUTextureViewDX11>> _handlesPerMip; // [slice][mip]
|
||||
|
||||
@@ -225,6 +226,11 @@ public:
|
||||
ASSERT(_desc.Flags & GPUTextureFlags::ReadOnlyDepthView);
|
||||
return (GPUTextureView*)&_handleReadOnlyDepth;
|
||||
}
|
||||
GPUTextureView* ViewStencil() const override
|
||||
{
|
||||
ASSERT(_desc.Flags & GPUTextureFlags::DepthStencil);
|
||||
return (GPUTextureView*)&_handleStencil;
|
||||
}
|
||||
void* GetNativePtr() const override
|
||||
{
|
||||
return static_cast<void*>(_resource);
|
||||
|
||||
@@ -136,8 +136,13 @@ bool GPUBufferDX12::OnInit()
|
||||
|
||||
// Create resource
|
||||
ID3D12Resource* resource;
|
||||
#if PLATFORM_WINDOWS
|
||||
D3D12_HEAP_FLAGS heapFlags = D3D12_HEAP_FLAG_CREATE_NOT_ZEROED;
|
||||
#else
|
||||
D3D12_HEAP_FLAGS heapFlags = D3D12_HEAP_FLAG_NONE;
|
||||
#endif
|
||||
D3D12_RESOURCE_STATES initialState = D3D12_RESOURCE_STATE_COMMON;
|
||||
VALIDATE_DIRECTX_CALL(_device->GetDevice()->CreateCommittedResource(&heapProperties, D3D12_HEAP_FLAG_NONE, &resourceDesc, initialState, nullptr, IID_PPV_ARGS(&resource)));
|
||||
VALIDATE_DIRECTX_CALL(_device->GetDevice()->CreateCommittedResource(&heapProperties, heapFlags, &resourceDesc, initialState, nullptr, IID_PPV_ARGS(&resource)));
|
||||
|
||||
// Set state
|
||||
initResource(resource, initialState, 1);
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
#include "CommandSignatureDX12.h"
|
||||
#include "Engine/Profiler/RenderStats.h"
|
||||
#include "Engine/Graphics/GPUResourceAccess.h"
|
||||
#include "Engine/Graphics/PixelFormatExtensions.h"
|
||||
#include "Engine/Graphics/Shaders/GPUShader.h"
|
||||
#include "Engine/Threading/Threading.h"
|
||||
|
||||
@@ -823,7 +824,10 @@ void GPUContextDX12::ClearDepth(GPUTextureView* depthBuffer, float depthValue, u
|
||||
SetResourceState(depthBufferDX12->GetResourceOwner(), D3D12_RESOURCE_STATE_DEPTH_WRITE, depthBufferDX12->SubresourceIndex);
|
||||
flushRBs();
|
||||
|
||||
_commandList->ClearDepthStencilView(depthBufferDX12->DSV(), D3D12_CLEAR_FLAG_DEPTH, depthValue, stencilValue, 0, nullptr);
|
||||
D3D12_CLEAR_FLAGS clearFlags = D3D12_CLEAR_FLAG_DEPTH;
|
||||
if (PixelFormatExtensions::HasStencil(depthBufferDX12->GetFormat()))
|
||||
clearFlags |= D3D12_CLEAR_FLAG_STENCIL;
|
||||
_commandList->ClearDepthStencilView(depthBufferDX12->DSV(), clearFlags, depthValue, stencilValue, 0, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -307,6 +307,32 @@ bool GPUDeviceDX12::Init()
|
||||
LOG(Info, "Hardware Version: {0}", hwVer);
|
||||
updateFrameEvents();
|
||||
|
||||
// Setup display output
|
||||
auto& videoOutput = VideoOutputs.AddOne();
|
||||
videoOutput.Name = hwVer;
|
||||
ComPtr<IDXGIDevice1> dxgiDevice;
|
||||
VALIDATE_DIRECTX_CALL(_device->QueryInterface(IID_GRAPHICS_PPV_ARGS(&dxgiDevice)));
|
||||
ComPtr<IDXGIAdapter> dxgiAdapter;
|
||||
VALIDATE_DIRECTX_CALL(dxgiDevice->GetAdapter(dxgiAdapter.GetAddressOf()));
|
||||
ComPtr<IDXGIOutput> dxgiOutput;
|
||||
VALIDATE_DIRECTX_CALL(dxgiAdapter->EnumOutputs(0, dxgiOutput.GetAddressOf()));
|
||||
DXGI_FORMAT backbufferFormat = RenderToolsDX::ToDxgiFormat(GPU_BACK_BUFFER_PIXEL_FORMAT);
|
||||
UINT modesCount = 0;
|
||||
VALIDATE_DIRECTX_CALL(dxgiOutput->GetDisplayModeList(backbufferFormat, 0, &modesCount, NULL));
|
||||
Array<DXGIXBOX_MODE_DESC> modes;
|
||||
modes.Resize((int32)modesCount);
|
||||
VALIDATE_DIRECTX_CALL(dxgiOutput->GetDisplayModeListX(backbufferFormat, 0, &modesCount, modes.Get()));
|
||||
for (const DXGIXBOX_MODE_DESC& mode : modes)
|
||||
{
|
||||
if (mode.Width > videoOutput.Width)
|
||||
{
|
||||
videoOutput.Width = mode.Width;
|
||||
videoOutput.Height = mode.Height;
|
||||
}
|
||||
videoOutput.RefreshRate = Math::Max(videoOutput.RefreshRate, mode.RefreshRate.Numerator / (float)mode.RefreshRate.Denominator);
|
||||
}
|
||||
modes.Resize(0);
|
||||
|
||||
#if PLATFORM_GDK
|
||||
GDKPlatform::Suspended.Bind<GPUDeviceDX12, &GPUDeviceDX12::OnSuspended>(this);
|
||||
GDKPlatform::Resumed.Bind<GPUDeviceDX12, &GPUDeviceDX12::OnResumed>(this);
|
||||
@@ -943,6 +969,7 @@ void GPUDeviceDX12::updateFrameEvents()
|
||||
dxgiAdapter->GetDesc(&_adapter->Description);
|
||||
ComPtr<IDXGIOutput> dxgiOutput;
|
||||
VALIDATE_DIRECTX_CALL(dxgiAdapter->EnumOutputs(0, dxgiOutput.GetAddressOf()));
|
||||
// TODO: support 120/40/30/24 fps
|
||||
VALIDATE_DIRECTX_CALL(_device->SetFrameIntervalX(dxgiOutput.Get(), D3D12XBOX_FRAME_INTERVAL_60_HZ, DX12_BACK_BUFFER_COUNT - 1u, D3D12XBOX_FRAME_INTERVAL_FLAG_NONE));
|
||||
VALIDATE_DIRECTX_CALL(_device->ScheduleFrameEventX(D3D12XBOX_FRAME_EVENT_ORIGIN, 0U, nullptr, D3D12XBOX_SCHEDULE_FRAME_EVENT_FLAG_NONE));
|
||||
}
|
||||
|
||||
@@ -159,7 +159,12 @@ bool GPUTextureDX12::OnInit()
|
||||
initialState = D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE | D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE;
|
||||
|
||||
// Create texture
|
||||
auto result = device->CreateCommittedResource(&heapProperties, D3D12_HEAP_FLAG_NONE, &resourceDesc, initialState, clearValuePtr, IID_PPV_ARGS(&resource));
|
||||
#if PLATFORM_WINDOWS
|
||||
D3D12_HEAP_FLAGS heapFlags = useRTV || useDSV ? D3D12_HEAP_FLAG_CREATE_NOT_ZEROED : D3D12_HEAP_FLAG_NONE;
|
||||
#else
|
||||
D3D12_HEAP_FLAGS heapFlags = D3D12_HEAP_FLAG_NONE;
|
||||
#endif
|
||||
auto result = device->CreateCommittedResource(&heapProperties, heapFlags, &resourceDesc, initialState, clearValuePtr, IID_PPV_ARGS(&resource));
|
||||
LOG_DIRECTX_RESULT_WITH_RETURN(result, true);
|
||||
|
||||
// Set state
|
||||
@@ -226,6 +231,8 @@ void GPUTextureDX12::OnReleaseGPU()
|
||||
_handlesPerSlice.Resize(0, false);
|
||||
_handleArray.Release();
|
||||
_handleVolume.Release();
|
||||
_handleReadOnlyDepth.Release();
|
||||
_handleStencil.Release();
|
||||
_srv.Release();
|
||||
_uav.Release();
|
||||
releaseResource();
|
||||
@@ -720,6 +727,45 @@ void GPUTextureDX12::initHandles()
|
||||
_handleReadOnlyDepth.SetSRV(srDesc);
|
||||
}
|
||||
}
|
||||
|
||||
// Stencil view
|
||||
if (useDSV && useSRV && PixelFormatExtensions::HasStencil(format))
|
||||
{
|
||||
PixelFormat stencilFormat;
|
||||
switch (_dxgiFormatDSV)
|
||||
{
|
||||
case PixelFormat::D24_UNorm_S8_UInt:
|
||||
srDesc.Format = DXGI_FORMAT_X24_TYPELESS_G8_UINT;
|
||||
stencilFormat = PixelFormat::X24_Typeless_G8_UInt;
|
||||
break;
|
||||
case PixelFormat::D32_Float_S8X24_UInt:
|
||||
srDesc.Format = DXGI_FORMAT_X32_TYPELESS_G8X24_UINT;
|
||||
stencilFormat = PixelFormat::X32_Typeless_G8X24_UInt;
|
||||
break;
|
||||
}
|
||||
if (isCubeMap)
|
||||
{
|
||||
srDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURECUBE;
|
||||
srDesc.TextureCube.MostDetailedMip = 0;
|
||||
srDesc.TextureCube.MipLevels = mipLevels;
|
||||
srDesc.TextureCube.ResourceMinLODClamp = 0;
|
||||
}
|
||||
else if (isMsaa)
|
||||
{
|
||||
srDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2DMS;
|
||||
}
|
||||
else
|
||||
{
|
||||
srDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D;
|
||||
srDesc.Texture2D.MostDetailedMip = 0;
|
||||
srDesc.Texture2D.MipLevels = mipLevels;
|
||||
srDesc.Texture2D.ResourceMinLODClamp = 0;
|
||||
srDesc.Texture2D.PlaneSlice = 1;
|
||||
}
|
||||
_handleStencil.Init(this, _device, this, stencilFormat, msaa);
|
||||
_handleStencil.ReadOnlyDepthView = true;
|
||||
_handleStencil.SetSRV(srDesc);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -91,7 +91,7 @@ public:
|
||||
// [IShaderResourceDX12]
|
||||
bool IsDepthStencilResource() const override
|
||||
{
|
||||
return _dsv.IsValid();
|
||||
return ReadOnlyDepthView || _dsv.IsValid();
|
||||
}
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE SRV() const override
|
||||
{
|
||||
@@ -117,6 +117,7 @@ private:
|
||||
GPUTextureViewDX12 _handleArray;
|
||||
GPUTextureViewDX12 _handleVolume;
|
||||
GPUTextureViewDX12 _handleReadOnlyDepth;
|
||||
GPUTextureViewDX12 _handleStencil;
|
||||
Array<GPUTextureViewDX12> _handlesPerSlice; // [slice]
|
||||
Array<Array<GPUTextureViewDX12>> _handlesPerMip; // [slice][mip]
|
||||
|
||||
@@ -165,6 +166,11 @@ public:
|
||||
ASSERT(_desc.Flags & GPUTextureFlags::ReadOnlyDepthView);
|
||||
return (GPUTextureView*)&_handleReadOnlyDepth;
|
||||
}
|
||||
GPUTextureView* ViewStencil() const override
|
||||
{
|
||||
ASSERT(_desc.Flags & GPUTextureFlags::DepthStencil);
|
||||
return (GPUTextureView*)&_handleStencil;
|
||||
}
|
||||
void* GetNativePtr() const override
|
||||
{
|
||||
return (void*)_resource;
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include "GPUDeviceDX.h"
|
||||
#include "Engine/Core/Types/DateTime.h"
|
||||
#include "Engine/Core/Types/StringBuilder.h"
|
||||
#include "Engine/Profiler/ProfilerCPU.h"
|
||||
#include "Engine/Graphics/GPUDevice.h"
|
||||
#include "IncludeDirectXHeaders.h"
|
||||
#include <winerror.h>
|
||||
@@ -21,6 +22,9 @@ typedef void* LPCDLGTEMPLATE;
|
||||
#pragma comment(lib, "SetupAPI.lib")
|
||||
#endif
|
||||
|
||||
#define DISPLAY_DEVICE_ACTIVE 0x00000001
|
||||
#define DISPLAY_DEVICE_MIRRORING_DRIVER 0x00000008
|
||||
|
||||
namespace Windows
|
||||
{
|
||||
typedef struct _devicemodeW
|
||||
@@ -84,7 +88,18 @@ namespace Windows
|
||||
DWORD dmPanningHeight;
|
||||
} DEVMODEW, *PDEVMODEW, *NPDEVMODEW, *LPDEVMODEW;
|
||||
|
||||
typedef struct _DISPLAY_DEVICEW
|
||||
{
|
||||
DWORD cb;
|
||||
WCHAR DeviceName[32];
|
||||
WCHAR DeviceString[128];
|
||||
DWORD StateFlags;
|
||||
WCHAR DeviceID[128];
|
||||
WCHAR DeviceKey[128];
|
||||
} DISPLAY_DEVICEW, *PDISPLAY_DEVICEW, *LPDISPLAY_DEVICEW;
|
||||
|
||||
WIN_API BOOL WIN_API_CALLCONV EnumDisplaySettingsW(LPCWSTR lpszDeviceName, DWORD iModeNum, DEVMODEW* lpDevMode);
|
||||
WIN_API BOOL WIN_API_CALLCONV EnumDisplayDevicesW(LPCWSTR lpDevice, DWORD iDevNum, PDISPLAY_DEVICEW lpDisplayDevice, DWORD dwFlags);
|
||||
}
|
||||
|
||||
// @formatter:off
|
||||
@@ -590,13 +605,14 @@ void GPUAdapterDX::SetDriverVersion(Version& ver)
|
||||
DriverVersion = ver;
|
||||
}
|
||||
|
||||
#if PLATFORM_WINDOWS
|
||||
|
||||
void GPUDeviceDX::UpdateOutputs(IDXGIAdapter* adapter)
|
||||
{
|
||||
#if PLATFORM_WINDOWS
|
||||
// Collect output devices
|
||||
PROFILE_CPU();
|
||||
uint32 outputIdx = 0;
|
||||
ComPtr<IDXGIOutput> output;
|
||||
DXGI_FORMAT defaultBackbufferFormat = RenderToolsDX::ToDxgiFormat(GPU_BACK_BUFFER_PIXEL_FORMAT);
|
||||
DXGI_FORMAT backbufferFormat = RenderToolsDX::ToDxgiFormat(GPU_BACK_BUFFER_PIXEL_FORMAT);
|
||||
Array<DXGI_MODE_DESC> modeDesc;
|
||||
while (adapter->EnumOutputs(outputIdx, &output) != DXGI_ERROR_NOT_FOUND)
|
||||
{
|
||||
@@ -606,7 +622,7 @@ void GPUDeviceDX::UpdateOutputs(IDXGIAdapter* adapter)
|
||||
output->GetDesc(&outputDX11.Desc);
|
||||
|
||||
uint32 numModes = 0;
|
||||
HRESULT hr = output->GetDisplayModeList(defaultBackbufferFormat, 0, &numModes, nullptr);
|
||||
HRESULT hr = output->GetDisplayModeList(backbufferFormat, 0, &numModes, nullptr);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
LOG(Warning, "Error while enumerating adapter output video modes.");
|
||||
@@ -614,7 +630,7 @@ void GPUDeviceDX::UpdateOutputs(IDXGIAdapter* adapter)
|
||||
}
|
||||
|
||||
modeDesc.Resize(numModes, false);
|
||||
hr = output->GetDisplayModeList(defaultBackbufferFormat, 0, &numModes, modeDesc.Get());
|
||||
hr = output->GetDisplayModeList(backbufferFormat, 0, &numModes, modeDesc.Get());
|
||||
if (FAILED(hr))
|
||||
{
|
||||
LOG(Warning, "Error while enumerating adapter output video modes.");
|
||||
@@ -635,16 +651,10 @@ void GPUDeviceDX::UpdateOutputs(IDXGIAdapter* adapter)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!foundVideoMode)
|
||||
{
|
||||
outputDX11.VideoModes.Add(mode);
|
||||
|
||||
// Collect only from the main monitor
|
||||
if (Outputs.Count() == 1)
|
||||
{
|
||||
VideoOutputModes.Add({ mode.Width, mode.Height, (uint32)(mode.RefreshRate.Numerator / (float)mode.RefreshRate.Denominator) });
|
||||
}
|
||||
VideoOutputModes.Add({ mode.Width, mode.Height, mode.RefreshRate.Numerator / (float)mode.RefreshRate.Denominator, VideoOutputs.Count() });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -659,24 +669,57 @@ void GPUDeviceDX::UpdateOutputs(IDXGIAdapter* adapter)
|
||||
devMode.dmDriverExtra = 0;
|
||||
Windows::EnumDisplaySettingsW(monitorInfo.szDevice, ((DWORD)-1), &devMode);
|
||||
|
||||
// Initialize display mode for Desktop
|
||||
DXGI_MODE_DESC currentMode;
|
||||
currentMode.Width = devMode.dmPelsWidth;
|
||||
currentMode.Height = devMode.dmPelsHeight;
|
||||
bool useDefaultRefreshRate = 1 == devMode.dmDisplayFrequency || 0 == devMode.dmDisplayFrequency;
|
||||
currentMode.RefreshRate.Numerator = useDefaultRefreshRate ? 0 : devMode.dmDisplayFrequency;
|
||||
currentMode.RefreshRate.Denominator = useDefaultRefreshRate ? 0 : 1;
|
||||
currentMode.Format = defaultBackbufferFormat;
|
||||
currentMode.Format = backbufferFormat;
|
||||
currentMode.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
|
||||
currentMode.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
|
||||
|
||||
if (output->FindClosestMatchingMode(¤tMode, &outputDX11.DesktopViewMode, nullptr) != S_OK)
|
||||
outputDX11.DesktopViewMode = currentMode;
|
||||
|
||||
float refreshRate = outputDX11.DesktopViewMode.RefreshRate.Numerator / (float)outputDX11.DesktopViewMode.RefreshRate.Denominator;
|
||||
LOG(Info, "Video output '{0}' {1}x{2} {3} Hz", outputDX11.Desc.DeviceName, devMode.dmPelsWidth, devMode.dmPelsHeight, refreshRate);
|
||||
// Add video output
|
||||
auto& videoOutput = VideoOutputs.AddOne();
|
||||
videoOutput.Width = devMode.dmPelsWidth;
|
||||
videoOutput.Height = devMode.dmPelsHeight;
|
||||
videoOutput.RefreshRate = outputDX11.DesktopViewMode.RefreshRate.Numerator / (float)outputDX11.DesktopViewMode.RefreshRate.Denominator;
|
||||
|
||||
// Query display device name
|
||||
Windows::DISPLAY_DEVICEW displayDevice;
|
||||
displayDevice.cb = sizeof(displayDevice);
|
||||
DWORD monitorIndex = 0;
|
||||
while (Windows::EnumDisplayDevicesW(outputDX11.Desc.DeviceName, monitorIndex, &displayDevice, 0))
|
||||
{
|
||||
if (displayDevice.StateFlags & DISPLAY_DEVICE_ACTIVE && !(displayDevice.StateFlags & DISPLAY_DEVICE_MIRRORING_DRIVER))
|
||||
{
|
||||
StringView id(displayDevice.DeviceID);
|
||||
videoOutput.Name = id.Substring(8, id.Substring(9).Find(TEXT('\\')) + 1);
|
||||
break;
|
||||
}
|
||||
monitorIndex++;
|
||||
}
|
||||
if (videoOutput.Name.IsEmpty())
|
||||
videoOutput.Name = outputDX11.Desc.DeviceName;
|
||||
|
||||
#ifdef __IDXGIOutput6_INTERFACE_DEFINED__
|
||||
// Query HDR support
|
||||
ComPtr<IDXGIOutput6> output6;
|
||||
if (SUCCEEDED(output->QueryInterface(IID_PPV_ARGS(&output6))))
|
||||
{
|
||||
DXGI_OUTPUT_DESC1 outputDesc;
|
||||
output6->GetDesc1(&outputDesc);
|
||||
videoOutput.HDR = outputDesc.ColorSpace == DXGI_COLOR_SPACE_RGB_FULL_G2084_NONE_P2020;
|
||||
}
|
||||
#endif
|
||||
|
||||
outputIdx++;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -33,6 +33,10 @@ public:
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
GPUTextureView* ViewStencil() const override
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
void* GetNativePtr() const override
|
||||
{
|
||||
return nullptr;
|
||||
|
||||
@@ -1388,7 +1388,7 @@ void GPUContextVulkan::UpdateBuffer(GPUBuffer* buffer, const void* data, uint32
|
||||
}
|
||||
else
|
||||
{
|
||||
auto allocation = _device->UploadBuffer.Upload(data, size, 4);
|
||||
auto allocation = _device->UploadBuffer.Upload(data, size, PLATFORM_MEMORY_ALIGNMENT);
|
||||
|
||||
VkBufferCopy region;
|
||||
region.size = size;
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
#include "Engine/Graphics/Textures/TextureData.h"
|
||||
#include "Engine/Scripting/Enums.h"
|
||||
|
||||
void GPUTextureViewVulkan::Init(GPUDeviceVulkan* device, ResourceOwnerVulkan* owner, VkImage image, int32 totalMipLevels, PixelFormat format, MSAALevel msaa, VkExtent3D extent, VkImageViewType viewType, int32 mipLevels, int32 firstMipIndex, int32 arraySize, int32 firstArraySlice, bool readOnlyDepth)
|
||||
void GPUTextureViewVulkan::Init(GPUDeviceVulkan* device, ResourceOwnerVulkan* owner, VkImage image, int32 totalMipLevels, PixelFormat format, MSAALevel msaa, VkExtent3D extent, VkImageViewType viewType, int32 mipLevels, int32 firstMipIndex, int32 arraySize, int32 firstArraySlice, bool readOnlyDepth, bool stencilView)
|
||||
{
|
||||
ASSERT(View == VK_NULL_HANDLE);
|
||||
|
||||
@@ -57,7 +57,13 @@ void GPUTextureViewVulkan::Init(GPUDeviceVulkan* device, ResourceOwnerVulkan* ow
|
||||
SubresourceIndex = RenderTools::CalcSubresourceIndex(firstMipIndex, firstArraySlice, totalMipLevels);
|
||||
}
|
||||
|
||||
if (PixelFormatExtensions::IsDepthStencil(format))
|
||||
if (stencilView)
|
||||
{
|
||||
range.aspectMask = VK_IMAGE_ASPECT_STENCIL_BIT;
|
||||
LayoutRTV = readOnlyDepth ? VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL : VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
|
||||
LayoutSRV = VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL;
|
||||
}
|
||||
else if (PixelFormatExtensions::IsDepthStencil(format))
|
||||
{
|
||||
range.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
|
||||
#if 0
|
||||
@@ -157,13 +163,23 @@ void GPUTextureViewVulkan::DescriptorAsImage(GPUContextVulkan* context, VkImageV
|
||||
imageView = View;
|
||||
layout = LayoutSRV;
|
||||
const VkImageAspectFlags aspectMask = Info.subresourceRange.aspectMask;
|
||||
if (aspectMask == (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT))
|
||||
if (aspectMask & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT))
|
||||
{
|
||||
// Transition depth-only when binding depth buffer with stencil
|
||||
// Transition depth-only when binding depth buffer with stencil (or stencil-only without depth)
|
||||
if (ViewSRV == VK_NULL_HANDLE)
|
||||
{
|
||||
VkImageViewCreateInfo createInfo = Info;
|
||||
createInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
|
||||
if (aspectMask == VK_IMAGE_ASPECT_STENCIL_BIT)
|
||||
{
|
||||
// Stencil
|
||||
createInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_STENCIL_BIT;
|
||||
createInfo.components.g = VK_COMPONENT_SWIZZLE_R; // Map .g component in shader to .r of stencil plane
|
||||
}
|
||||
else
|
||||
{
|
||||
// Depth
|
||||
createInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
|
||||
}
|
||||
VALIDATE_VULKAN_RESULT(vkCreateImageView(Device->Device, &createInfo, nullptr, &ViewSRV));
|
||||
}
|
||||
imageView = ViewSRV;
|
||||
@@ -434,6 +450,26 @@ void GPUTextureVulkan::initHandles()
|
||||
{
|
||||
_handleReadOnlyDepth.Init(_device, this, _image, mipLevels, format, msaa, extent, VK_IMAGE_VIEW_TYPE_2D, mipLevels, 0, 1, 0, true);
|
||||
}
|
||||
|
||||
// Stencil view
|
||||
if (IsDepthStencil() && IsShaderResource() && PixelFormatExtensions::HasStencil(format))
|
||||
{
|
||||
PixelFormat stencilFormat;
|
||||
switch (format)
|
||||
{
|
||||
case PixelFormat::D24_UNorm_S8_UInt:
|
||||
case PixelFormat::R24_UNorm_X8_Typeless:
|
||||
case PixelFormat::R24G8_Typeless:
|
||||
stencilFormat = PixelFormat::X24_Typeless_G8_UInt;
|
||||
break;
|
||||
case PixelFormat::D32_Float_S8X24_UInt:
|
||||
case PixelFormat::R32_Float_X8X24_Typeless:
|
||||
case PixelFormat::R32G8X24_Typeless:
|
||||
stencilFormat = PixelFormat::X32_Typeless_G8X24_UInt;
|
||||
break;
|
||||
}
|
||||
_handleStencil.Init(_device, this, _image, mipLevels, stencilFormat, msaa, extent, VK_IMAGE_VIEW_TYPE_2D, mipLevels, 0, 1, 0, true, true);
|
||||
}
|
||||
}
|
||||
|
||||
void GPUTextureVulkan::OnResidentMipsChanged()
|
||||
@@ -457,6 +493,7 @@ void GPUTextureVulkan::OnReleaseGPU()
|
||||
_handleVolume.Release();
|
||||
_handleUAV.Release();
|
||||
_handleReadOnlyDepth.Release();
|
||||
_handleStencil.Release();
|
||||
for (int32 i = 0; i < _handlesPerMip.Count(); i++)
|
||||
{
|
||||
for (int32 j = 0; j < _handlesPerMip[i].Count(); j++)
|
||||
|
||||
@@ -45,7 +45,7 @@ public:
|
||||
#endif
|
||||
|
||||
public:
|
||||
void Init(GPUDeviceVulkan* device, ResourceOwnerVulkan* owner, VkImage image, int32 totalMipLevels, PixelFormat format, MSAALevel msaa, VkExtent3D extent, VkImageViewType viewType, int32 mipLevels = 1, int32 firstMipIndex = 0, int32 arraySize = 1, int32 firstArraySlice = 0, bool readOnlyDepth = false);
|
||||
void Init(GPUDeviceVulkan* device, ResourceOwnerVulkan* owner, VkImage image, int32 totalMipLevels, PixelFormat format, MSAALevel msaa, VkExtent3D extent, VkImageViewType viewType, int32 mipLevels = 1, int32 firstMipIndex = 0, int32 arraySize = 1, int32 firstArraySlice = 0, bool readOnlyDepth = false, bool stencilView = false);
|
||||
|
||||
VkImageView GetFramebufferView();
|
||||
|
||||
@@ -79,6 +79,7 @@ private:
|
||||
GPUTextureViewVulkan _handleVolume;
|
||||
GPUTextureViewVulkan _handleUAV;
|
||||
GPUTextureViewVulkan _handleReadOnlyDepth;
|
||||
GPUTextureViewVulkan _handleStencil;
|
||||
Array<GPUTextureViewVulkan> _handlesPerSlice; // [slice]
|
||||
Array<Array<GPUTextureViewVulkan>> _handlesPerMip; // [slice][mip]
|
||||
|
||||
@@ -140,6 +141,11 @@ public:
|
||||
ASSERT(_desc.Flags & GPUTextureFlags::ReadOnlyDepthView);
|
||||
return (GPUTextureView*)&_handleReadOnlyDepth;
|
||||
}
|
||||
GPUTextureView* ViewStencil() const override
|
||||
{
|
||||
ASSERT(_desc.Flags & GPUTextureFlags::DepthStencil);
|
||||
return (GPUTextureView*)&_handleStencil;
|
||||
}
|
||||
void* GetNativePtr() const override
|
||||
{
|
||||
return (void*)_image;
|
||||
|
||||
@@ -111,6 +111,7 @@ UploadBufferVulkan::Allocation UploadBufferVulkan::Allocate(uint64 size, uint64
|
||||
|
||||
// Move within a page
|
||||
_currentOffset += size;
|
||||
ASSERT_LOW_LAYER(_currentOffset <= _currentPage->Size);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user