Fixed SRG compile issue with metal which leads to multiple gpu crashes inlucde ImGuiPass render crash (#6315)
Signed-off-by: Qing Tao <55564570+VickyAtAZ@users.noreply.github.com>
This commit is contained in:
@@ -60,10 +60,19 @@ namespace AZ
|
||||
|
||||
NSError* error = nil;
|
||||
id<MTLLibrary> lib = nil;
|
||||
|
||||
|
||||
bool loadFromByteCode = false;
|
||||
|
||||
// MacOS Big Sur (11.16.x) has issue loading some shader's byte code when GPUCapture(Metal) is on.
|
||||
// Only enable it for Monterey (12.x)
|
||||
if(@available(iOS 14.0, macOS 12.0, *))
|
||||
{
|
||||
loadFromByteCode = true;
|
||||
}
|
||||
|
||||
const uint8_t* shaderByteCode = reinterpret_cast<const uint8_t*>(shaderFunction->GetByteCode().data());
|
||||
const int byteCodeLength = shaderFunction->GetByteCode().size();
|
||||
if(byteCodeLength > 0 )
|
||||
if(byteCodeLength > 0 && loadFromByteCode)
|
||||
{
|
||||
dispatch_data_t dispatchByteCodeData = dispatch_data_create(shaderByteCode, byteCodeLength, NULL, DISPATCH_DATA_DESTRUCTOR_DEFAULT);
|
||||
lib = [mtlDevice newLibraryWithData:dispatchByteCodeData error:&error];
|
||||
@@ -73,7 +82,7 @@ namespace AZ
|
||||
//In case byte code was not generated try to create the lib with source code
|
||||
MTLCompileOptions* compileOptions = [MTLCompileOptions alloc];
|
||||
compileOptions.fastMathEnabled = YES;
|
||||
compileOptions.languageVersion = MTLLanguageVersion2_0;
|
||||
compileOptions.languageVersion = MTLLanguageVersion2_2;
|
||||
lib = [mtlDevice newLibraryWithSource:source
|
||||
options:compileOptions
|
||||
error:&error];
|
||||
|
||||
@@ -1,126 +1,117 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include <RHI/ArgumentBuffer.h>
|
||||
#include <RHI/Conversions.h>
|
||||
#include <RHI/Device.h>
|
||||
#include <RHI/ShaderResourceGroup.h>
|
||||
#include <RHI/ShaderResourceGroupPool.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
namespace Metal
|
||||
{
|
||||
RHI::Ptr<ShaderResourceGroupPool> ShaderResourceGroupPool::Create()
|
||||
{
|
||||
return aznew ShaderResourceGroupPool();
|
||||
}
|
||||
|
||||
RHI::ResultCode ShaderResourceGroupPool::InitInternal(RHI::Device& deviceBase, const RHI::ShaderResourceGroupPoolDescriptor& descriptor)
|
||||
{
|
||||
Device& device = static_cast<Device&>(deviceBase);
|
||||
m_device = &device;
|
||||
m_srgLayout = descriptor.m_layout;
|
||||
return RHI::ResultCode::Success;
|
||||
}
|
||||
|
||||
void ShaderResourceGroupPool::ShutdownInternal()
|
||||
{
|
||||
Base::ShutdownInternal();
|
||||
}
|
||||
|
||||
RHI::ResultCode ShaderResourceGroupPool::InitGroupInternal(RHI::ShaderResourceGroup& groupBase)
|
||||
{
|
||||
ShaderResourceGroup& group = static_cast<ShaderResourceGroup&>(groupBase);
|
||||
|
||||
for (size_t i = 0; i < RHI::Limits::Device::FrameCountMax; ++i)
|
||||
{
|
||||
auto argBuffer = ArgumentBuffer::Create();
|
||||
argBuffer->Init(m_device, m_srgLayout, group, this);
|
||||
group.m_compiledArgBuffers[i] = argBuffer;
|
||||
}
|
||||
|
||||
return RHI::ResultCode::Success;
|
||||
}
|
||||
|
||||
void ShaderResourceGroupPool::ShutdownResourceInternal(RHI::Resource& resourceBase)
|
||||
{
|
||||
ShaderResourceGroup& group = static_cast<ShaderResourceGroup&>(resourceBase);
|
||||
for (size_t i = 0; i < RHI::Limits::Device::FrameCountMax; ++i)
|
||||
{
|
||||
group.m_compiledArgBuffers[i] = nullptr;
|
||||
}
|
||||
Base::ShutdownResourceInternal(resourceBase);
|
||||
}
|
||||
|
||||
RHI::ResultCode ShaderResourceGroupPool::CompileGroupInternal(RHI::ShaderResourceGroup& groupBase, const RHI::ShaderResourceGroupData& groupData)
|
||||
{
|
||||
ShaderResourceGroup& group = static_cast<ShaderResourceGroup&>(groupBase);
|
||||
group.UpdateCompiledDataIndex();
|
||||
|
||||
if (!groupData.IsAnyResourceTypeUpdated())
|
||||
{
|
||||
return RHI::ResultCode::Success;
|
||||
}
|
||||
|
||||
ArgumentBuffer& argBuffer = *group.m_compiledArgBuffers[group.m_compiledDataIndex];
|
||||
argBuffer.ClearResourceTracking();
|
||||
|
||||
auto constantData = groupData.GetConstantData();
|
||||
if (!constantData.empty() && groupData.IsResourceTypeEnabledForCompilation(static_cast<uint32_t>(RHI::ShaderResourceGroupData::ResourceTypeMask::ConstantDataMask)))
|
||||
{
|
||||
argBuffer.UpdateConstantBufferViews(groupData.GetConstantData());
|
||||
}
|
||||
|
||||
const RHI::ShaderResourceGroupLayout* layout = groupData.GetLayout();
|
||||
uint32_t shaderInputIndex = 0;
|
||||
if (groupData.IsResourceTypeEnabledForCompilation(static_cast<uint32_t>(RHI::ShaderResourceGroupData::ResourceTypeMask::ImageViewMask)))
|
||||
{
|
||||
for (const RHI::ShaderInputImageDescriptor& shaderInputImage : layout->GetShaderInputListForImages())
|
||||
{
|
||||
const RHI::ShaderInputImageIndex imageInputIndex(shaderInputIndex);
|
||||
AZStd::array_view<RHI::ConstPtr<RHI::ImageView>> imageViews = groupData.GetImageViewArray(imageInputIndex);
|
||||
argBuffer.UpdateImageViews(shaderInputImage, imageInputIndex, imageViews);
|
||||
++shaderInputIndex;
|
||||
}
|
||||
}
|
||||
|
||||
if (groupData.IsResourceTypeEnabledForCompilation(static_cast<uint32_t>(RHI::ShaderResourceGroupData::ResourceTypeMask::SamplerMask)))
|
||||
{
|
||||
shaderInputIndex = 0;
|
||||
for (const RHI::ShaderInputSamplerDescriptor& shaderInputSampler : layout->GetShaderInputListForSamplers())
|
||||
{
|
||||
const RHI::ShaderInputSamplerIndex samplerInputIndex(shaderInputIndex);
|
||||
AZStd::array_view<RHI::SamplerState> samplerStates = groupData.GetSamplerArray(samplerInputIndex);
|
||||
argBuffer.UpdateSamplers(shaderInputSampler, samplerInputIndex, samplerStates);
|
||||
++shaderInputIndex;
|
||||
}
|
||||
}
|
||||
|
||||
if (groupData.IsResourceTypeEnabledForCompilation(static_cast<uint32_t>(RHI::ShaderResourceGroupData::ResourceTypeMask::BufferViewMask)))
|
||||
{
|
||||
shaderInputIndex = 0;
|
||||
for (const RHI::ShaderInputBufferDescriptor& shaderInputBuffer : layout->GetShaderInputListForBuffers())
|
||||
{
|
||||
const RHI::ShaderInputBufferIndex bufferInputIndex(shaderInputIndex);
|
||||
AZStd::array_view<RHI::ConstPtr<RHI::BufferView>> bufferViews = groupData.GetBufferViewArray(bufferInputIndex);
|
||||
argBuffer.UpdateBufferViews(shaderInputBuffer, bufferInputIndex, bufferViews);
|
||||
++shaderInputIndex;
|
||||
}
|
||||
}
|
||||
|
||||
return RHI::ResultCode::Success;
|
||||
}
|
||||
|
||||
void ShaderResourceGroupPool::OnFrameEnd()
|
||||
{
|
||||
Base::OnFrameEnd();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include <RHI/ArgumentBuffer.h>
|
||||
#include <RHI/Conversions.h>
|
||||
#include <RHI/Device.h>
|
||||
#include <RHI/ShaderResourceGroup.h>
|
||||
#include <RHI/ShaderResourceGroupPool.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
namespace Metal
|
||||
{
|
||||
RHI::Ptr<ShaderResourceGroupPool> ShaderResourceGroupPool::Create()
|
||||
{
|
||||
return aznew ShaderResourceGroupPool();
|
||||
}
|
||||
|
||||
RHI::ResultCode ShaderResourceGroupPool::InitInternal(RHI::Device& deviceBase, const RHI::ShaderResourceGroupPoolDescriptor& descriptor)
|
||||
{
|
||||
Device& device = static_cast<Device&>(deviceBase);
|
||||
m_device = &device;
|
||||
m_srgLayout = descriptor.m_layout;
|
||||
return RHI::ResultCode::Success;
|
||||
}
|
||||
|
||||
void ShaderResourceGroupPool::ShutdownInternal()
|
||||
{
|
||||
Base::ShutdownInternal();
|
||||
}
|
||||
|
||||
RHI::ResultCode ShaderResourceGroupPool::InitGroupInternal(RHI::ShaderResourceGroup& groupBase)
|
||||
{
|
||||
ShaderResourceGroup& group = static_cast<ShaderResourceGroup&>(groupBase);
|
||||
|
||||
for (size_t i = 0; i < RHI::Limits::Device::FrameCountMax; ++i)
|
||||
{
|
||||
auto argBuffer = ArgumentBuffer::Create();
|
||||
argBuffer->Init(m_device, m_srgLayout, group, this);
|
||||
group.m_compiledArgBuffers[i] = argBuffer;
|
||||
}
|
||||
|
||||
return RHI::ResultCode::Success;
|
||||
}
|
||||
|
||||
void ShaderResourceGroupPool::ShutdownResourceInternal(RHI::Resource& resourceBase)
|
||||
{
|
||||
ShaderResourceGroup& group = static_cast<ShaderResourceGroup&>(resourceBase);
|
||||
for (size_t i = 0; i < RHI::Limits::Device::FrameCountMax; ++i)
|
||||
{
|
||||
group.m_compiledArgBuffers[i] = nullptr;
|
||||
}
|
||||
Base::ShutdownResourceInternal(resourceBase);
|
||||
}
|
||||
|
||||
RHI::ResultCode ShaderResourceGroupPool::CompileGroupInternal(RHI::ShaderResourceGroup& groupBase, const RHI::ShaderResourceGroupData& groupData)
|
||||
{
|
||||
ShaderResourceGroup& group = static_cast<ShaderResourceGroup&>(groupBase);
|
||||
|
||||
if (!groupData.IsAnyResourceTypeUpdated())
|
||||
{
|
||||
return RHI::ResultCode::Success;
|
||||
}
|
||||
|
||||
group.UpdateCompiledDataIndex();
|
||||
ArgumentBuffer& argBuffer = *group.m_compiledArgBuffers[group.m_compiledDataIndex];
|
||||
argBuffer.ClearResourceTracking();
|
||||
|
||||
auto constantData = groupData.GetConstantData();
|
||||
if (!constantData.empty())
|
||||
{
|
||||
argBuffer.UpdateConstantBufferViews(groupData.GetConstantData());
|
||||
}
|
||||
|
||||
const RHI::ShaderResourceGroupLayout* layout = groupData.GetLayout();
|
||||
uint32_t shaderInputIndex = 0;
|
||||
for (const RHI::ShaderInputImageDescriptor& shaderInputImage : layout->GetShaderInputListForImages())
|
||||
{
|
||||
const RHI::ShaderInputImageIndex imageInputIndex(shaderInputIndex);
|
||||
AZStd::array_view<RHI::ConstPtr<RHI::ImageView>> imageViews = groupData.GetImageViewArray(imageInputIndex);
|
||||
argBuffer.UpdateImageViews(shaderInputImage, imageInputIndex, imageViews);
|
||||
++shaderInputIndex;
|
||||
}
|
||||
|
||||
shaderInputIndex = 0;
|
||||
for (const RHI::ShaderInputSamplerDescriptor& shaderInputSampler : layout->GetShaderInputListForSamplers())
|
||||
{
|
||||
const RHI::ShaderInputSamplerIndex samplerInputIndex(shaderInputIndex);
|
||||
AZStd::array_view<RHI::SamplerState> samplerStates = groupData.GetSamplerArray(samplerInputIndex);
|
||||
argBuffer.UpdateSamplers(shaderInputSampler, samplerInputIndex, samplerStates);
|
||||
++shaderInputIndex;
|
||||
}
|
||||
|
||||
shaderInputIndex = 0;
|
||||
for (const RHI::ShaderInputBufferDescriptor& shaderInputBuffer : layout->GetShaderInputListForBuffers())
|
||||
{
|
||||
const RHI::ShaderInputBufferIndex bufferInputIndex(shaderInputIndex);
|
||||
AZStd::array_view<RHI::ConstPtr<RHI::BufferView>> bufferViews = groupData.GetBufferViewArray(bufferInputIndex);
|
||||
argBuffer.UpdateBufferViews(shaderInputBuffer, bufferInputIndex, bufferViews);
|
||||
++shaderInputIndex;
|
||||
}
|
||||
|
||||
return RHI::ResultCode::Success;
|
||||
}
|
||||
|
||||
void ShaderResourceGroupPool::OnFrameEnd()
|
||||
{
|
||||
Base::OnFrameEnd();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user