Add warnings on incorrect GPUBuffer or GPUTexture usage when binding to GPUContext (in non-release builds)
This commit is contained in:
@@ -11,6 +11,53 @@ GPUContext::GPUContext(GPUDevice* device)
|
||||
{
|
||||
}
|
||||
|
||||
#if !BUILD_RELEASE
|
||||
|
||||
#include "Engine/Core/Log.h"
|
||||
|
||||
void GPUContext::LogInvalidResourceUsage(int32 slot, const GPUResourceView* view, InvalidBindPoint bindPoint)
|
||||
{
|
||||
GPUResource* resource = view ? view->GetParent() : nullptr;
|
||||
const Char* resourceType = TEXT("resource");
|
||||
const Char* flagType = TEXT("flags");
|
||||
if (resource)
|
||||
{
|
||||
switch (resource->GetResourceType())
|
||||
{
|
||||
case GPUResourceType::RenderTarget:
|
||||
case GPUResourceType::Texture:
|
||||
case GPUResourceType::CubeTexture:
|
||||
case GPUResourceType::VolumeTexture:
|
||||
resourceType = TEXT("texture");
|
||||
flagType = TEXT("GPUTextureFlags");
|
||||
break;
|
||||
case GPUResourceType::Buffer:
|
||||
resourceType = TEXT("buffer");
|
||||
flagType = TEXT("GPUBufferFlags");
|
||||
break;
|
||||
}
|
||||
}
|
||||
const Char* usage = TEXT("-");
|
||||
switch (bindPoint)
|
||||
{
|
||||
case InvalidBindPoint::SRV:
|
||||
usage = TEXT("shader resource");
|
||||
break;
|
||||
case InvalidBindPoint::UAV:
|
||||
usage = TEXT("unordered access");
|
||||
break;
|
||||
case InvalidBindPoint::DSV:
|
||||
usage = TEXT("depth stencil");
|
||||
break;
|
||||
case InvalidBindPoint::RTV:
|
||||
usage = TEXT("render target");
|
||||
break;
|
||||
}
|
||||
LOG(Error, "Incorrect {} bind at slot {} as {} (ensure to setup correct {} when creating that resource)", resourceType, slot, usage, flagType);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void GPUContext::FrameBegin()
|
||||
{
|
||||
_lastRenderTime = Platform::GetTimeSeconds();
|
||||
|
||||
@@ -121,6 +121,12 @@ protected:
|
||||
double _lastRenderTime = -1;
|
||||
GPUContext(GPUDevice* device);
|
||||
|
||||
#if !BUILD_RELEASE
|
||||
enum class InvalidBindPoint { SRV, UAV, DSV, RTV };
|
||||
|
||||
static void LogInvalidResourceUsage(int32 slot, const GPUResourceView* view, InvalidBindPoint bindPoint);
|
||||
#endif
|
||||
|
||||
public:
|
||||
/// <summary>
|
||||
/// Gets the graphics device.
|
||||
@@ -143,7 +149,6 @@ public:
|
||||
|
||||
public:
|
||||
#if GPU_ALLOW_PROFILE_EVENTS
|
||||
|
||||
/// <summary>
|
||||
/// Begins the profile event.
|
||||
/// </summary>
|
||||
@@ -158,7 +163,6 @@ public:
|
||||
virtual void EventEnd()
|
||||
{
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
public:
|
||||
|
||||
@@ -190,6 +190,7 @@ API_CLASS(Abstract, NoSpawn, Attributes="HideInEditor") class FLAXENGINE_API GPU
|
||||
DECLARE_SCRIPTING_TYPE_NO_SPAWN(GPUResourceView);
|
||||
protected:
|
||||
static double DummyLastRenderTime;
|
||||
GPUResource* _parent = nullptr;
|
||||
|
||||
explicit GPUResourceView(const SpawnParams& params)
|
||||
: ScriptingObject(params)
|
||||
@@ -201,6 +202,14 @@ public:
|
||||
// Points to the cache used by the resource for the resource visibility/usage detection. Written during rendering when resource view is used.
|
||||
double* LastRenderTime;
|
||||
|
||||
/// <summary>
|
||||
/// Gets parent GPU resource owning that view.
|
||||
/// </summary>
|
||||
API_PROPERTY() FORCE_INLINE GPUResource* GetParent() const
|
||||
{
|
||||
return _parent;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the native pointer to the underlying view. It's a platform-specific handle.
|
||||
/// </summary>
|
||||
|
||||
@@ -21,7 +21,6 @@ API_CLASS(Sealed, NoSpawn) class FLAXENGINE_API GPUTextureView : public GPUResou
|
||||
{
|
||||
DECLARE_SCRIPTING_TYPE_NO_SPAWN(GPUTextureView);
|
||||
protected:
|
||||
GPUResource* _parent = nullptr;
|
||||
PixelFormat _format = PixelFormat::Unknown;
|
||||
MSAALevel _msaa = MSAALevel::None;
|
||||
|
||||
@@ -40,14 +39,6 @@ protected:
|
||||
}
|
||||
|
||||
public:
|
||||
/// <summary>
|
||||
/// Gets parent GPU resource owning that view.
|
||||
/// </summary>
|
||||
API_PROPERTY() FORCE_INLINE GPUResource* GetParent() const
|
||||
{
|
||||
return _parent;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the view format.
|
||||
/// </summary>
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
GPUBufferDX11::GPUBufferDX11(GPUDeviceDX11* device, const StringView& name)
|
||||
: GPUResourceDX11(device, name)
|
||||
{
|
||||
_view.SetParnet(this);
|
||||
}
|
||||
|
||||
GPUBufferView* GPUBufferDX11::View() const
|
||||
|
||||
@@ -40,6 +40,11 @@ public:
|
||||
|
||||
public:
|
||||
|
||||
void SetParnet(GPUBuffer* parent)
|
||||
{
|
||||
_parent = parent;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Release the view.
|
||||
/// </summary>
|
||||
|
||||
@@ -355,7 +355,11 @@ void GPUContextDX11::BindCB(int32 slot, GPUConstantBuffer* cb)
|
||||
|
||||
void GPUContextDX11::BindSR(int32 slot, GPUResourceView* view)
|
||||
{
|
||||
#if !BUILD_RELEASE
|
||||
ASSERT(slot >= 0 && slot < GPU_MAX_SR_BINDED);
|
||||
if (view && ((IShaderResourceDX11*)view->GetNativePtr())->SRV() == nullptr)
|
||||
LogInvalidResourceUsage(slot, view, InvalidBindPoint::SRV);
|
||||
#endif
|
||||
auto handle = view ? ((IShaderResourceDX11*)view->GetNativePtr())->SRV() : nullptr;
|
||||
if (_srHandles[slot] != handle)
|
||||
{
|
||||
@@ -369,7 +373,11 @@ void GPUContextDX11::BindSR(int32 slot, GPUResourceView* view)
|
||||
|
||||
void GPUContextDX11::BindUA(int32 slot, GPUResourceView* view)
|
||||
{
|
||||
#if !BUILD_RELEASE
|
||||
ASSERT(slot >= 0 && slot < GPU_MAX_UA_BINDED);
|
||||
if (view && ((IShaderResourceDX11*)view->GetNativePtr())->UAV() == nullptr)
|
||||
LogInvalidResourceUsage(slot, view, InvalidBindPoint::UAV);
|
||||
#endif
|
||||
auto handle = view ? ((IShaderResourceDX11*)view->GetNativePtr())->UAV() : nullptr;
|
||||
if (_uaHandles[slot] != handle)
|
||||
{
|
||||
|
||||
@@ -12,13 +12,11 @@
|
||||
class IShaderResourceDX11
|
||||
{
|
||||
public:
|
||||
|
||||
IShaderResourceDX11()
|
||||
{
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
/// <summary>
|
||||
/// Gets handle to the shader resource view object.
|
||||
/// </summary>
|
||||
@@ -28,7 +26,6 @@ public:
|
||||
/// <summary>
|
||||
/// Gets CPU to the unordered access view object.
|
||||
/// </summary>
|
||||
/// <returns>UAV</returns>
|
||||
virtual ID3D11UnorderedAccessView* UAV() const = 0;
|
||||
};
|
||||
|
||||
|
||||
@@ -6,18 +6,6 @@
|
||||
#include "GPUDeviceDX12.h"
|
||||
#include "Engine/GraphicsDevice/DirectX/RenderToolsDX.h"
|
||||
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE DescriptorHeapWithSlotsDX12::Slot::CPU() const
|
||||
{
|
||||
ASSERT_LOW_LAYER(Heap);
|
||||
return Heap->CPU(Index);
|
||||
}
|
||||
|
||||
D3D12_GPU_DESCRIPTOR_HANDLE DescriptorHeapWithSlotsDX12::Slot::GPU() const
|
||||
{
|
||||
ASSERT_LOW_LAYER(Heap);
|
||||
return Heap->GPU(Index);
|
||||
}
|
||||
|
||||
void DescriptorHeapWithSlotsDX12::Slot::CreateSRV(GPUDeviceDX12* device, ID3D12Resource* resource, D3D12_SHADER_RESOURCE_VIEW_DESC* desc)
|
||||
{
|
||||
if (Heap == nullptr)
|
||||
|
||||
@@ -35,8 +35,15 @@ public:
|
||||
}
|
||||
#endif
|
||||
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE CPU() const;
|
||||
D3D12_GPU_DESCRIPTOR_HANDLE GPU() const;
|
||||
FORCE_INLINE D3D12_CPU_DESCRIPTOR_HANDLE CPU() const
|
||||
{
|
||||
return Heap ? Heap->CPU(Index) : D3D12_CPU_DESCRIPTOR_HANDLE {};
|
||||
}
|
||||
|
||||
FORCE_INLINE D3D12_GPU_DESCRIPTOR_HANDLE GPU() const
|
||||
{
|
||||
return Heap ? Heap->GPU(Index) : D3D12_GPU_DESCRIPTOR_HANDLE {};
|
||||
}
|
||||
|
||||
void CreateSRV(GPUDeviceDX12* device, ID3D12Resource* resource, D3D12_SHADER_RESOURCE_VIEW_DESC* desc = nullptr);
|
||||
void CreateRTV(GPUDeviceDX12* device, ID3D12Resource* resource, D3D12_RENDER_TARGET_VIEW_DESC* desc = nullptr);
|
||||
|
||||
@@ -189,7 +189,7 @@ bool GPUBufferDX12::OnInit()
|
||||
}
|
||||
|
||||
// Create views
|
||||
_view.Init(_device, this);
|
||||
_view.Init(_device, this, this);
|
||||
if (useSRV)
|
||||
{
|
||||
D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc;
|
||||
|
||||
@@ -46,10 +46,12 @@ public:
|
||||
/// </summary>
|
||||
/// <param name="device">The graphics device.</param>
|
||||
/// <param name="owner">The resource owner.</param>
|
||||
void Init(GPUDeviceDX12* device, ResourceOwnerDX12* owner)
|
||||
/// <param name="parent">The parent resource.</param>
|
||||
void Init(GPUDeviceDX12* device, ResourceOwnerDX12* owner, GPUResource* parent)
|
||||
{
|
||||
_device = device;
|
||||
_owner = owner;
|
||||
_parent = parent;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -926,9 +926,13 @@ void GPUContextDX12::BindCB(int32 slot, GPUConstantBuffer* cb)
|
||||
|
||||
void GPUContextDX12::BindSR(int32 slot, GPUResourceView* view)
|
||||
{
|
||||
#if !BUILD_RELEASE
|
||||
ASSERT(slot >= 0 && slot < GPU_MAX_SR_BINDED);
|
||||
if (view && ((IShaderResourceDX12*)view->GetNativePtr())->SRV().ptr == 0)
|
||||
LogInvalidResourceUsage(slot, view, InvalidBindPoint::SRV);
|
||||
#endif
|
||||
auto handle = view ? (IShaderResourceDX12*)view->GetNativePtr() : nullptr;
|
||||
if (_srHandles[slot] != handle || !handle)
|
||||
if (_srHandles[slot] != handle)
|
||||
{
|
||||
_srMaskDirtyGraphics |= 1 << slot;
|
||||
_srMaskDirtyCompute |= 1 << slot;
|
||||
@@ -940,7 +944,11 @@ void GPUContextDX12::BindSR(int32 slot, GPUResourceView* view)
|
||||
|
||||
void GPUContextDX12::BindUA(int32 slot, GPUResourceView* view)
|
||||
{
|
||||
#if !BUILD_RELEASE
|
||||
ASSERT(slot >= 0 && slot < GPU_MAX_UA_BINDED);
|
||||
if (view && ((IShaderResourceDX12*)view->GetNativePtr())->UAV().ptr == 0)
|
||||
LogInvalidResourceUsage(slot, view, InvalidBindPoint::UAV);
|
||||
#endif
|
||||
_uaHandles[slot] = view ? (IShaderResourceDX12*)view->GetNativePtr() : nullptr;
|
||||
if (view)
|
||||
*view->LastRenderTime = _lastRenderTime;
|
||||
|
||||
@@ -13,6 +13,7 @@ void GPUBufferViewVulkan::Init(GPUDeviceVulkan* device, GPUBufferVulkan* owner,
|
||||
{
|
||||
ASSERT(View == VK_NULL_HANDLE);
|
||||
|
||||
_parent = owner;
|
||||
Device = device;
|
||||
Owner = owner;
|
||||
Buffer = buffer;
|
||||
|
||||
@@ -46,6 +46,10 @@ public:
|
||||
void DescriptorAsUniformTexelBuffer(GPUContextVulkan* context, VkBufferView& bufferView) override;
|
||||
void DescriptorAsStorageBuffer(GPUContextVulkan* context, VkBuffer& buffer, VkDeviceSize& offset, VkDeviceSize& range) override;
|
||||
void DescriptorAsStorageTexelBuffer(GPUContextVulkan* context, VkBufferView& bufferView) override;
|
||||
#if !BUILD_RELEASE
|
||||
bool HasSRV() const override { return ((GPUBuffer*)_parent)->IsShaderResource(); }
|
||||
bool HasUAV() const override { return ((GPUBuffer*)_parent)->IsUnorderedAccess(); }
|
||||
#endif
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -1001,7 +1001,11 @@ void GPUContextVulkan::BindCB(int32 slot, GPUConstantBuffer* cb)
|
||||
|
||||
void GPUContextVulkan::BindSR(int32 slot, GPUResourceView* view)
|
||||
{
|
||||
#if !BUILD_RELEASE
|
||||
ASSERT(slot >= 0 && slot < GPU_MAX_SR_BINDED);
|
||||
if (view && ((DescriptorOwnerResourceVulkan*)view->GetNativePtr())->HasSRV() == false)
|
||||
LogInvalidResourceUsage(slot, view, InvalidBindPoint::SRV);
|
||||
#endif
|
||||
const auto handle = view ? (DescriptorOwnerResourceVulkan*)view->GetNativePtr() : nullptr;
|
||||
if (_srHandles[slot] != handle)
|
||||
{
|
||||
@@ -1013,7 +1017,11 @@ void GPUContextVulkan::BindSR(int32 slot, GPUResourceView* view)
|
||||
|
||||
void GPUContextVulkan::BindUA(int32 slot, GPUResourceView* view)
|
||||
{
|
||||
#if !BUILD_RELEASE
|
||||
ASSERT(slot >= 0 && slot < GPU_MAX_UA_BINDED);
|
||||
if (view && ((DescriptorOwnerResourceVulkan*)view->GetNativePtr())->HasUAV() == false)
|
||||
LogInvalidResourceUsage(slot, view, InvalidBindPoint::UAV);
|
||||
#endif
|
||||
const auto handle = view ? (DescriptorOwnerResourceVulkan*)view->GetNativePtr() : nullptr;
|
||||
if (_uaHandles[slot] != handle)
|
||||
{
|
||||
|
||||
@@ -722,6 +722,12 @@ public:
|
||||
{
|
||||
CRASH;
|
||||
}
|
||||
|
||||
#if !BUILD_RELEASE
|
||||
// Utilities for incorrect resource usage.
|
||||
virtual bool HasSRV() const { return false; }
|
||||
virtual bool HasUAV() const { return false; }
|
||||
#endif
|
||||
};
|
||||
|
||||
extern GPUDevice* CreateGPUDeviceVulkan();
|
||||
|
||||
@@ -77,6 +77,10 @@ public:
|
||||
// [DescriptorOwnerResourceVulkan]
|
||||
void DescriptorAsImage(GPUContextVulkan* context, VkImageView& imageView, VkImageLayout& layout) override;
|
||||
void DescriptorAsStorageImage(GPUContextVulkan* context, VkImageView& imageView, VkImageLayout& layout) override;
|
||||
#if !BUILD_RELEASE
|
||||
bool HasSRV() const override { return ((GPUTexture*)_parent)->IsShaderResource(); }
|
||||
bool HasUAV() const override { return ((GPUTexture*)_parent)->IsUnorderedAccess(); }
|
||||
#endif
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
|
||||
Reference in New Issue
Block a user