mirror of
https://github.com/godotengine/godot-angle-static.git
synced 2025-12-31 01:48:22 +03:00
Metal: Validate max render target size without an allocation
We would allocate a MTLRenderPassDescriptor for validating an internal error case only to throw it away immediately afterwards. This happened on every new render pass. This allocation/release amounts to about 10% of ANGLE's CPU time when running Chrome. Bug: chromium:1466696 Change-Id: I0bbe086c0b8006d2ff15ae57f25b591f791acb60 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/4706925 Commit-Queue: Geoff Lang <geofflang@chromium.org> Reviewed-by: Shahbaz Youssefi <syoussefi@chromium.org>
This commit is contained in:
committed by
Angle LUCI CQ
parent
085f25bbb1
commit
f586ec98d9
@@ -1907,22 +1907,16 @@ mtl::RenderCommandEncoder *ContextMtl::getRenderPassCommandEncoder(const mtl::Re
|
||||
const mtl::ContextDevice &metalDevice = getMetalDevice();
|
||||
if (mtl::DeviceHasMaximumRenderTargetSize(metalDevice))
|
||||
{
|
||||
ANGLE_MTL_OBJC_SCOPE
|
||||
NSUInteger maxSize = mtl::GetMaxRenderTargetSizeForDeviceInBytes(metalDevice);
|
||||
NSUInteger renderTargetSize =
|
||||
ComputeTotalSizeUsedForMTLRenderPassDescriptor(desc, this, metalDevice);
|
||||
if (renderTargetSize > maxSize)
|
||||
{
|
||||
MTLRenderPassDescriptor *objCDesc = [MTLRenderPassDescriptor renderPassDescriptor];
|
||||
desc.convertToMetalDesc(objCDesc, getNativeCaps().maxColorAttachments);
|
||||
NSUInteger maxSize = mtl::GetMaxRenderTargetSizeForDeviceInBytes(metalDevice);
|
||||
NSUInteger renderTargetSize =
|
||||
ComputeTotalSizeUsedForMTLRenderPassDescriptor(objCDesc, this, metalDevice);
|
||||
if (renderTargetSize > maxSize)
|
||||
{
|
||||
std::stringstream errorStream;
|
||||
errorStream << "This set of render targets requires " << renderTargetSize
|
||||
<< " bytes of pixel storage. This device supports " << maxSize
|
||||
<< " bytes.";
|
||||
ANGLE_MTL_HANDLE_ERROR(this, errorStream.str().c_str(), GL_INVALID_OPERATION);
|
||||
return nil;
|
||||
}
|
||||
std::stringstream errorStream;
|
||||
errorStream << "This set of render targets requires " << renderTargetSize
|
||||
<< " bytes of pixel storage. This device supports " << maxSize << " bytes.";
|
||||
ANGLE_MTL_HANDLE_ERROR(this, errorStream.str().c_str(), GL_INVALID_OPERATION);
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
return &mRenderEncoder.restart(desc, getNativeCaps().maxColorAttachments);
|
||||
|
||||
@@ -185,7 +185,7 @@ bool DeviceHasMaximumRenderTargetSize(id<MTLDevice> device);
|
||||
// has alpha channel.
|
||||
MTLClearColor EmulatedAlphaClearColor(MTLClearColor color, MTLColorWriteMask colorMask);
|
||||
|
||||
NSUInteger ComputeTotalSizeUsedForMTLRenderPassDescriptor(const MTLRenderPassDescriptor *descriptor,
|
||||
NSUInteger ComputeTotalSizeUsedForMTLRenderPassDescriptor(const mtl::RenderPassDesc &descriptor,
|
||||
const Context *context,
|
||||
const mtl::ContextDevice &device);
|
||||
|
||||
|
||||
@@ -1577,7 +1577,24 @@ static NSUInteger getNextLocationForFormat(const FormatCaps &caps,
|
||||
return currentRenderTargetSize;
|
||||
}
|
||||
|
||||
NSUInteger ComputeTotalSizeUsedForMTLRenderPassDescriptor(const MTLRenderPassDescriptor *descriptor,
|
||||
static NSUInteger getNextLocationForAttachment(const mtl::RenderPassAttachmentDesc &attachment,
|
||||
const Context *context,
|
||||
NSUInteger currentRenderTargetSize)
|
||||
{
|
||||
mtl::TextureRef texture =
|
||||
attachment.implicitMSTexture ? attachment.implicitMSTexture : attachment.texture;
|
||||
|
||||
if (texture)
|
||||
{
|
||||
MTLPixelFormat pixelFormat = texture->pixelFormat();
|
||||
bool isMsaa = texture->samples();
|
||||
const FormatCaps &caps = context->getDisplay()->getNativeFormatCaps(pixelFormat);
|
||||
currentRenderTargetSize = getNextLocationForFormat(caps, isMsaa, currentRenderTargetSize);
|
||||
}
|
||||
return currentRenderTargetSize;
|
||||
}
|
||||
|
||||
NSUInteger ComputeTotalSizeUsedForMTLRenderPassDescriptor(const mtl::RenderPassDesc &descriptor,
|
||||
const Context *context,
|
||||
const mtl::ContextDevice &device)
|
||||
{
|
||||
@@ -1585,48 +1602,25 @@ NSUInteger ComputeTotalSizeUsedForMTLRenderPassDescriptor(const MTLRenderPassDes
|
||||
|
||||
for (NSUInteger i = 0; i < GetMaxNumberOfRenderTargetsForDevice(device); i++)
|
||||
{
|
||||
MTLPixelFormat pixelFormat = descriptor.colorAttachments[i].texture.pixelFormat;
|
||||
bool isMsaa = descriptor.colorAttachments[i].texture.sampleCount > 1;
|
||||
if (pixelFormat != MTLPixelFormatInvalid)
|
||||
{
|
||||
const FormatCaps &caps = context->getDisplay()->getNativeFormatCaps(pixelFormat);
|
||||
currentRenderTargetSize =
|
||||
getNextLocationForFormat(caps, isMsaa, currentRenderTargetSize);
|
||||
}
|
||||
currentRenderTargetSize = getNextLocationForAttachment(descriptor.colorAttachments[i],
|
||||
context, currentRenderTargetSize);
|
||||
}
|
||||
if (descriptor.depthAttachment.texture.pixelFormat ==
|
||||
descriptor.stencilAttachment.texture.pixelFormat)
|
||||
if (descriptor.depthAttachment.texture == descriptor.stencilAttachment.texture)
|
||||
{
|
||||
bool isMsaa = descriptor.depthAttachment.texture.sampleCount > 1;
|
||||
if (descriptor.depthAttachment.texture.pixelFormat != MTLPixelFormatInvalid)
|
||||
{
|
||||
const FormatCaps &caps = context->getDisplay()->getNativeFormatCaps(
|
||||
descriptor.depthAttachment.texture.pixelFormat);
|
||||
currentRenderTargetSize =
|
||||
getNextLocationForFormat(caps, isMsaa, currentRenderTargetSize);
|
||||
}
|
||||
currentRenderTargetSize = getNextLocationForAttachment(descriptor.depthAttachment, context,
|
||||
currentRenderTargetSize);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (descriptor.depthAttachment.texture.pixelFormat != MTLPixelFormatInvalid)
|
||||
{
|
||||
bool isMsaa = descriptor.depthAttachment.texture.sampleCount > 1;
|
||||
const FormatCaps &caps = context->getDisplay()->getNativeFormatCaps(
|
||||
descriptor.depthAttachment.texture.pixelFormat);
|
||||
currentRenderTargetSize =
|
||||
getNextLocationForFormat(caps, isMsaa, currentRenderTargetSize);
|
||||
}
|
||||
if (descriptor.stencilAttachment.texture.pixelFormat != MTLPixelFormatInvalid)
|
||||
{
|
||||
bool isMsaa = descriptor.stencilAttachment.texture.sampleCount > 1;
|
||||
const FormatCaps &caps = context->getDisplay()->getNativeFormatCaps(
|
||||
descriptor.stencilAttachment.texture.pixelFormat);
|
||||
currentRenderTargetSize =
|
||||
getNextLocationForFormat(caps, isMsaa, currentRenderTargetSize);
|
||||
}
|
||||
currentRenderTargetSize = getNextLocationForAttachment(descriptor.depthAttachment, context,
|
||||
currentRenderTargetSize);
|
||||
currentRenderTargetSize = getNextLocationForAttachment(descriptor.stencilAttachment,
|
||||
context, currentRenderTargetSize);
|
||||
}
|
||||
|
||||
return currentRenderTargetSize;
|
||||
}
|
||||
|
||||
NSUInteger ComputeTotalSizeUsedForMTLRenderPipelineDescriptor(
|
||||
const MTLRenderPipelineDescriptor *descriptor,
|
||||
const Context *context,
|
||||
|
||||
Reference in New Issue
Block a user