Commit db180778 authored by Christopher Cameron's avatar Christopher Cameron Committed by Commit Bot

Metal: Defeat caching when testing shader link

There exists a literal in the test shader's binary. Add a list of
valid values that can be inserted at that location in the shader,
and choose one at random when testing shader link time. This
will defeat caching that Metal might be doing (at least for
a while).

Remove DumpWithoutCrashings on failure (we just skip recording
a UMA on failure).

Randomly choose between testing shader compile or shader link
at runtime, so we get distributions for both.

Bug: 974219
Change-Id: I61b067596a69884fcdf967b9774397d0112a6a0a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2209309
Commit-Queue: ccameron <ccameron@chromium.org>
Reviewed-by: default avatarLeonard Grey <lgrey@chromium.org>
Cr-Commit-Position: refs/heads/master@{#770908}
parent 9047326b
...@@ -4,10 +4,10 @@ ...@@ -4,10 +4,10 @@
#include "components/metal_util/test_shader.h" #include "components/metal_util/test_shader.h"
#include <CommonCrypto/CommonDigest.h>
#import <Metal/Metal.h> #import <Metal/Metal.h>
#include "base/bind.h" #include "base/bind.h"
#include "base/debug/dump_without_crashing.h"
#include "base/mac/scoped_dispatch_object.h" #include "base/mac/scoped_dispatch_object.h"
#include "base/mac/scoped_nsobject.h" #include "base/mac/scoped_nsobject.h"
#include "base/memory/ref_counted.h" #include "base/memory/ref_counted.h"
...@@ -17,15 +17,12 @@ ...@@ -17,15 +17,12 @@
#include "base/synchronization/lock.h" #include "base/synchronization/lock.h"
#include "base/task/post_task.h" #include "base/task/post_task.h"
#include "base/task/thread_pool.h" #include "base/task/thread_pool.h"
#include "components/crash/core/common/crash_key.h"
#include "components/metal_util/device.h" #include "components/metal_util/device.h"
namespace metal { namespace metal {
namespace { namespace {
constexpr uint32_t kCrashKeyLength = 1024;
const char* kTestShaderSource = const char* kTestShaderSource =
"" ""
"#include <metal_stdlib>\n" "#include <metal_stdlib>\n"
...@@ -51,7 +48,7 @@ const char* kTestShaderSource = ...@@ -51,7 +48,7 @@ const char* kTestShaderSource =
"}\n" "}\n"
""; "";
size_t kTestLibSize = 5990; size_t kTestLibSize = 0x1766;
uint8_t kTestLibData[] = { uint8_t kTestLibData[] = {
0x4d, 0x54, 0x4c, 0x42, 0x01, 0x80, 0x02, 0x00, 0x03, 0x00, 0x00, 0x00, 0x4d, 0x54, 0x4c, 0x42, 0x01, 0x80, 0x02, 0x00, 0x03, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x66, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
...@@ -554,8 +551,122 @@ uint8_t kTestLibData[] = { ...@@ -554,8 +551,122 @@ uint8_t kTestLibData[] = {
0x2e, 0x31, 0x34, 0x2e, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2e, 0x31, 0x34, 0x2e, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00}; 0x00, 0x00};
// There exists a 4-byte literal at this offset, which can be changed to any
// value in kValidLiteral to defeat caching.
const size_t kLiteralOffset = 0x167c;
const size_t kLiteralSize = 0x4;
const uint8_t kValidLiteralValues[] = {
0xef, 0x4c, 0x9a, 0x68, 0xef, 0x4c, 0x9a, 0x70, 0x66, 0x6f, 0xa6, 0x74,
0xef, 0x4c, 0x9a, 0x78, 0x2a, 0x5e, 0x9f, 0x7a, 0x66, 0x6f, 0xa6, 0x7c,
0xa2, 0x88, 0xab, 0x7e, 0xef, 0x4c, 0x9a, 0xa0, 0x7c, 0xd9, 0x9b, 0xa1,
0x2a, 0x5e, 0x9f, 0xa2, 0xb8, 0xea, 0xa2, 0xa3, 0x66, 0x6f, 0xa6, 0xa4,
0xf4, 0xfb, 0xa7, 0xa5, 0xa2, 0x88, 0xab, 0xa6, 0x2f, 0x0d, 0xaf, 0xa7,
0xef, 0x4c, 0x9a, 0xa8, 0x36, 0x0f, 0xdb, 0xa8, 0x7c, 0xd9, 0x9b, 0xa9,
0xe3, 0x9b, 0xde, 0xa9, 0x2a, 0x5e, 0x9f, 0xaa, 0x71, 0x28, 0xe2, 0xaa,
0xb8, 0xea, 0xa2, 0xab, 0xff, 0xac, 0xe3, 0xab, 0x66, 0x6f, 0xa6, 0xac,
0xad, 0x39, 0xe7, 0xac, 0xf4, 0xfb, 0xa7, 0xad, 0x3b, 0xbe, 0xea, 0xad,
0xa2, 0x88, 0xab, 0xae, 0xe8, 0x4a, 0xee, 0xae, 0x2f, 0x0d, 0xaf, 0xaf,
0x76, 0xcf, 0xef, 0xaf, 0x7c, 0xd9, 0x9b, 0xb1, 0xb0, 0x3a, 0xbe, 0xb1,
0xe3, 0x9b, 0xde, 0xb1, 0xf7, 0xfc, 0xfe, 0xb1, 0x2a, 0x5e, 0x9f, 0xb2,
0x3e, 0xbf, 0xbf, 0xb2, 0x71, 0x28, 0xe2, 0xb2, 0xb8, 0xea, 0xa2, 0xb3,
0xec, 0x4b, 0xc3, 0xb3, 0xff, 0xac, 0xe3, 0xb3, 0x32, 0x0e, 0x86, 0xb4,
0x66, 0x6f, 0xa6, 0xb4, 0x79, 0xd8, 0xc6, 0xb4, 0xad, 0x39, 0xe7, 0xb4,
0xe0, 0x9a, 0x87, 0xb5, 0xf4, 0xfb, 0xa7, 0xb5, 0x27, 0x5d, 0xca, 0xb5,
0x3b, 0xbe, 0xea, 0xb5, 0x6e, 0x1f, 0x8b, 0xb6, 0xa2, 0x88, 0xab, 0xb6,
0xb5, 0xe9, 0xcb, 0xb6, 0xe8, 0x4a, 0xee, 0xb6, 0xfc, 0xab, 0x8e, 0xb7,
0x2f, 0x0d, 0xaf, 0xb7, 0x63, 0x6e, 0xcf, 0xb7, 0x76, 0xcf, 0xef, 0xb7,
0x65, 0x1c, 0x8a, 0xb8, 0xef, 0x4c, 0x9a, 0xb8, 0x78, 0x7d, 0xaa, 0xb8,
0x22, 0xae, 0xba, 0xb8, 0xac, 0xde, 0xca, 0xb8, 0x36, 0x0f, 0xdb, 0xb8,
0xbf, 0x3f, 0xeb, 0xb8, 0x69, 0x78, 0xfb, 0xb8, 0xf3, 0xa8, 0x8b, 0xb9,
0x7c, 0xd9, 0x9b, 0xb9, 0x26, 0x0a, 0xae, 0xb9, 0xb0, 0x3a, 0xbe, 0xb9,
0x3a, 0x6b, 0xce, 0xb9, 0xe3, 0x9b, 0xde, 0xb9, 0x6d, 0xcc, 0xee, 0xb9,
0xf7, 0xfc, 0xfe, 0xb9, 0xa1, 0x2d, 0x8f, 0xba, 0x2a, 0x5e, 0x9f, 0xba,
0xb4, 0x8e, 0xaf, 0xba, 0x3e, 0xbf, 0xbf, 0xba, 0xe7, 0xef, 0xcf, 0xba,
0x71, 0x28, 0xe2, 0xba, 0xfb, 0x58, 0xf2, 0xba, 0x2e, 0xba, 0x92, 0xbb,
0xb8, 0xea, 0xa2, 0xbb, 0x62, 0x1b, 0xb3, 0xbb, 0xec, 0x4b, 0xc3, 0xbb,
0x75, 0x7c, 0xd3, 0xbb, 0xff, 0xac, 0xe3, 0xbb, 0xa9, 0xdd, 0xf3, 0xbb,
0x32, 0x0e, 0x86, 0xbc, 0xbc, 0x3e, 0x96, 0xbc, 0x66, 0x6f, 0xa6, 0xbc,
0xf0, 0x9f, 0xb6, 0xbc, 0x79, 0xd8, 0xc6, 0xbc, 0x23, 0x09, 0xd7, 0xbc,
0xad, 0x39, 0xe7, 0xbc, 0x37, 0x6a, 0xf7, 0xbc, 0xe0, 0x9a, 0x87, 0xbd,
0x6a, 0xcb, 0x97, 0xbd, 0xf4, 0xfb, 0xa7, 0xbd, 0x7d, 0x2c, 0xba, 0xbd,
0x27, 0x5d, 0xca, 0xbd, 0xb1, 0x8d, 0xda, 0xbd, 0x3b, 0xbe, 0xea, 0xbd,
0xe4, 0xee, 0xfa, 0xbd, 0x6e, 0x1f, 0x8b, 0xbe, 0xf8, 0x4f, 0x9b, 0xbe,
0xa2, 0x88, 0xab, 0xbe, 0x2b, 0xb9, 0xbb, 0xbe, 0xb5, 0xe9, 0xcb, 0xbe,
0x3f, 0x1a, 0xde, 0xbe, 0xe8, 0x4a, 0xee, 0xbe, 0x72, 0x7b, 0xfe, 0xbe,
0xfc, 0xab, 0x8e, 0xbf, 0xa6, 0xdc, 0x9e, 0xbf, 0x2f, 0x0d, 0xaf, 0xbf,
0xb9, 0x3d, 0xbf, 0xbf, 0x63, 0x6e, 0xcf, 0xbf, 0xed, 0x9e, 0xdf, 0xbf,
0x76, 0xcf, 0xef, 0xbf, 0x65, 0x1c, 0x8a, 0xe0, 0xaa, 0x38, 0x92, 0xe0,
0xef, 0x4c, 0x9a, 0xe0, 0x33, 0x69, 0xa2, 0xe0, 0x78, 0x7d, 0xaa, 0xe0,
0xbd, 0x99, 0xb2, 0xe0, 0x22, 0xae, 0xba, 0xe0, 0x67, 0xca, 0xc2, 0xe0,
0xac, 0xde, 0xca, 0xe0, 0xf1, 0xfa, 0xd2, 0xe0, 0x36, 0x0f, 0xdb, 0xe0,
0x7a, 0x2b, 0xe3, 0xe0, 0xbf, 0x3f, 0xeb, 0xe0, 0x24, 0x5c, 0xf3, 0xe0,
0x69, 0x78, 0xfb, 0xe0, 0xae, 0x8c, 0x83, 0xe1, 0xf3, 0xa8, 0x8b, 0xe1,
0x38, 0xbd, 0x93, 0xe1, 0x7c, 0xd9, 0x9b, 0xe1, 0xe1, 0xed, 0xa3, 0xe1,
0x26, 0x0a, 0xae, 0xe1, 0x6b, 0x1e, 0xb6, 0xe1, 0xb0, 0x3a, 0xbe, 0xe1,
0xf5, 0x4e, 0xc6, 0xe1, 0x3a, 0x6b, 0xce, 0xe1, 0x7e, 0x7f, 0xd6, 0xe1,
0xe3, 0x9b, 0xde, 0xe1, 0x28, 0xb8, 0xe6, 0xe1, 0x6d, 0xcc, 0xee, 0xe1,
0xb2, 0xe8, 0xf6, 0xe1, 0xf7, 0xfc, 0xfe, 0xe1, 0x3c, 0x19, 0x87, 0xe2,
0xa1, 0x2d, 0x8f, 0xe2, 0xe5, 0x49, 0x97, 0xe2, 0x2a, 0x5e, 0x9f, 0xe2,
0x6f, 0x7a, 0xa7, 0xe2, 0xb4, 0x8e, 0xaf, 0xe2, 0xf9, 0xaa, 0xb7, 0xe2,
0x3e, 0xbf, 0xbf, 0xe2, 0xa3, 0xdb, 0xc7, 0xe2, 0xe7, 0xef, 0xcf, 0xe2,
0x2c, 0x0c, 0xda, 0xe2, 0x71, 0x28, 0xe2, 0xe2, 0xb6, 0x3c, 0xea, 0xe2,
0xfb, 0x58, 0xf2, 0xe2, 0x60, 0x6d, 0xfa, 0xe2, 0xe9, 0x9d, 0x8a, 0xe3,
0x2e, 0xba, 0x92, 0xe3, 0x73, 0xce, 0x9a, 0xe3, 0xb8, 0xea, 0xa2, 0xe3,
0xfd, 0xfe, 0xaa, 0xe3, 0x62, 0x1b, 0xb3, 0xe3, 0xa7, 0x2f, 0xbb, 0xe3,
0xec, 0x4b, 0xc3, 0xe3, 0x30, 0x68, 0xcb, 0xe3, 0x75, 0x7c, 0xd3, 0xe3,
0xba, 0x98, 0xdb, 0xe3, 0xff, 0xac, 0xe3, 0xe3, 0x64, 0xc9, 0xeb, 0xe3,
0xa9, 0xdd, 0xf3, 0xe3, 0xee, 0xf9, 0xfb, 0xe3, 0x32, 0x0e, 0x86, 0xe4,
0x77, 0x2a, 0x8e, 0xe4, 0xbc, 0x3e, 0x96, 0xe4, 0x21, 0x5b, 0x9e, 0xe4,
0x66, 0x6f, 0xa6, 0xe4, 0xab, 0x8b, 0xae, 0xe4, 0xf0, 0x9f, 0xb6, 0xe4,
0x34, 0xbc, 0xbe, 0xe4, 0x79, 0xd8, 0xc6, 0xe4, 0xbe, 0xec, 0xce, 0xe4,
0x23, 0x09, 0xd7, 0xe4, 0x68, 0x1d, 0xdf, 0xe4, 0xad, 0x39, 0xe7, 0xe4,
0xf2, 0x4d, 0xef, 0xe4, 0x37, 0x6a, 0xf7, 0xe4, 0x7b, 0x7e, 0xff, 0xe4,
0xe0, 0x9a, 0x87, 0xe5, 0x25, 0xaf, 0x8f, 0xe5, 0x6a, 0xcb, 0x97, 0xe5,
0xaf, 0xdf, 0x9f, 0xe5, 0xf4, 0xfb, 0xa7, 0xe5, 0x39, 0x18, 0xb2, 0xe5,
0x7d, 0x2c, 0xba, 0xe5, 0xe2, 0x48, 0xc2, 0xe5, 0x27, 0x5d, 0xca, 0xe5,
0x6c, 0x79, 0xd2, 0xe5, 0xb1, 0x8d, 0xda, 0xe5, 0xf6, 0xa9, 0xe2, 0xe5,
0x3b, 0xbe, 0xea, 0xe5, 0x7f, 0xda, 0xf2, 0xe5, 0xe4, 0xee, 0xfa, 0xe5,
0x29, 0x0b, 0x83, 0xe6, 0x6e, 0x1f, 0x8b, 0xe6, 0xb3, 0x3b, 0x93, 0xe6,
0xf8, 0x4f, 0x9b, 0xe6, 0x3d, 0x6c, 0xa3, 0xe6, 0xa2, 0x88, 0xab, 0xe6,
0xe6, 0x9c, 0xb3, 0xe6, 0x2b, 0xb9, 0xbb, 0xe6, 0x70, 0xcd, 0xc3, 0xe6,
0xb5, 0xe9, 0xcb, 0xe6, 0xfa, 0xfd, 0xd3, 0xe6, 0x3f, 0x1a, 0xde, 0xe6,
0xa4, 0x2e, 0xe6, 0xe6, 0xe8, 0x4a, 0xee, 0xe6, 0x2d, 0x5f, 0xf6, 0xe6,
0x72, 0x7b, 0xfe, 0xe6, 0xb7, 0x8f, 0x86, 0xe7, 0xfc, 0xab, 0x8e, 0xe7,
0x61, 0xc8, 0x96, 0xe7, 0xa6, 0xdc, 0x9e, 0xe7, 0xea, 0xf8, 0xa6, 0xe7,
0x2f, 0x0d, 0xaf, 0xe7, 0x74, 0x29, 0xb7, 0xe7, 0xb9, 0x3d, 0xbf, 0xe7,
0xfe, 0x59, 0xc7, 0xe7, 0x63, 0x6e, 0xcf, 0xe7, 0xa8, 0x8a, 0xd7, 0xe7,
0xed, 0x9e, 0xdf, 0xe7, 0x31, 0xbb, 0xe7, 0xe7, 0x76, 0xcf, 0xef, 0xe7,
0xbb, 0xeb, 0xf7, 0xe7, 0x32, 0x0e, 0x86, 0xe8, 0x65, 0x1c, 0x8a, 0xe8,
0x77, 0x2a, 0x8e, 0xe8, 0xaa, 0x38, 0x92, 0xe8, 0xbc, 0x3e, 0x96, 0xe8,
0xef, 0x4c, 0x9a, 0xe8, 0x21, 0x5b, 0x9e, 0xe8, 0x33, 0x69, 0xa2, 0xe8,
0x66, 0x6f, 0xa6, 0xe8, 0x78, 0x7d, 0xaa, 0xe8, 0xab, 0x8b, 0xae, 0xe8,
0xbd, 0x99, 0xb2, 0xe8, 0xf0, 0x9f, 0xb6, 0xe8, 0x22, 0xae, 0xba, 0xe8,
};
// The sha256 hash of the bitcode is stored at this offset in the shader.
const size_t kTestLibHashOffset = 0x104;
// The bitcode that is hashed is stored at this offset and with this size.
const size_t kTestLibBitcodeOffset = 0xd16;
const size_t kTestLibBitcodeSize = 0xa50;
std::vector<uint8_t> GetAlteredLibraryData() {
// Make a copy of the shader's data.
std::vector<uint8_t> data(kTestLibData, kTestLibData + kTestLibSize);
// Alter the data at kLiteralOffset to defeat caching.
uint64_t index = base::RandInt(0, sizeof(kValidLiteralValues) / kLiteralSize);
for (size_t i = 0; i < kLiteralSize; ++i)
data[kLiteralOffset + i] = kValidLiteralValues[kLiteralSize * index + i];
// Compute the hash of the altered bitcode and and place it in the data.
CC_SHA256(&data[kTestLibBitcodeOffset], kTestLibBitcodeSize,
&data[kTestLibHashOffset]);
return data;
}
base::ScopedDispatchObject<dispatch_data_t> GetLibraryData() { base::ScopedDispatchObject<dispatch_data_t> GetLibraryData() {
std::vector<uint8_t> vector_data(kTestLibData, kTestLibData + kTestLibSize); auto vector_data = GetAlteredLibraryData();
base::ScopedDispatchObject<dispatch_data_t> dispatch_data( base::ScopedDispatchObject<dispatch_data_t> dispatch_data(
dispatch_data_create(vector_data.data(), vector_data.size(), nullptr, dispatch_data_create(vector_data.data(), vector_data.size(), nullptr,
DISPATCH_DATA_DESTRUCTOR_DEFAULT)); DISPATCH_DATA_DESTRUCTOR_DEFAULT));
...@@ -671,14 +782,8 @@ void TestRenderPipelineStateNow(base::scoped_nsprotocol<id<MTLDevice>> device, ...@@ -671,14 +782,8 @@ void TestRenderPipelineStateNow(base::scoped_nsprotocol<id<MTLDevice>> device,
[library newFunctionWithName:@"vertexShader"]); [library newFunctionWithName:@"vertexShader"]);
base::scoped_nsprotocol<id<MTLFunction>> fragment_fn( base::scoped_nsprotocol<id<MTLFunction>> fragment_fn(
[library newFunctionWithName:@"fragmentShader"]); [library newFunctionWithName:@"fragmentShader"]);
if (error || !library || !vertex_fn || !fragment_fn) { if (error || !library || !vertex_fn || !fragment_fn)
static crash_reporter::CrashKeyString<kCrashKeyLength> crash_key(
"newLibraryWithData");
crash_reporter::ScopedCrashKeyString value(
&crash_key, base::SysNSStringToUTF8([error description]));
base::debug::DumpWithoutCrashing();
return; return;
}
// Initialize the TestShaderState and post the timeout callback, before // Initialize the TestShaderState and post the timeout callback, before
// calling into the Metal API. // calling into the Metal API.
...@@ -697,13 +802,6 @@ void TestRenderPipelineStateNow(base::scoped_nsprotocol<id<MTLDevice>> device, ...@@ -697,13 +802,6 @@ void TestRenderPipelineStateNow(base::scoped_nsprotocol<id<MTLDevice>> device,
[descriptor colorAttachments][0].pixelFormat = MTLPixelFormatBGRA8Unorm; [descriptor colorAttachments][0].pixelFormat = MTLPixelFormatBGRA8Unorm;
MTLNewRenderPipelineStateCompletionHandler completion_handler = MTLNewRenderPipelineStateCompletionHandler completion_handler =
^(id<MTLRenderPipelineState> render_pipeline_state, NSError* error) { ^(id<MTLRenderPipelineState> render_pipeline_state, NSError* error) {
if (!render_pipeline_state) {
static crash_reporter::CrashKeyString<kCrashKeyLength> crash_key(
"newRenderPipelineStateWithDescriptor");
crash_reporter::ScopedCrashKeyString value(
&crash_key, base::SysNSStringToUTF8([error description]));
base::debug::DumpWithoutCrashing();
}
state->OnCompletionHandlerCalled(render_pipeline_state state->OnCompletionHandlerCalled(render_pipeline_state
? TestShaderResult::kSucceeded ? TestShaderResult::kSucceeded
: TestShaderResult::kFailed); : TestShaderResult::kFailed);
...@@ -734,13 +832,6 @@ void TestShaderNow(base::scoped_nsprotocol<id<MTLDevice>> device, ...@@ -734,13 +832,6 @@ void TestShaderNow(base::scoped_nsprotocol<id<MTLDevice>> device,
[[MTLCompileOptions alloc] init]); [[MTLCompileOptions alloc] init]);
MTLNewLibraryCompletionHandler completion_handler = MTLNewLibraryCompletionHandler completion_handler =
^(id<MTLLibrary> library, NSError* error) { ^(id<MTLLibrary> library, NSError* error) {
if (!library) {
static crash_reporter::CrashKeyString<kCrashKeyLength> crash_key(
"newLibraryWithSource");
crash_reporter::ScopedCrashKeyString value(
&crash_key, base::SysNSStringToUTF8([error description]));
base::debug::DumpWithoutCrashing();
}
state->OnCompletionHandlerCalled(library ? TestShaderResult::kSucceeded state->OnCompletionHandlerCalled(library ? TestShaderResult::kSucceeded
: TestShaderResult::kFailed); : TestShaderResult::kFailed);
}; };
...@@ -755,8 +846,9 @@ void TestShaderNow(base::scoped_nsprotocol<id<MTLDevice>> device, ...@@ -755,8 +846,9 @@ void TestShaderNow(base::scoped_nsprotocol<id<MTLDevice>> device,
void TestShader(TestShaderCallback callback, void TestShader(TestShaderCallback callback,
const base::TimeDelta& delay, const base::TimeDelta& delay,
const base::TimeDelta& timeout) { const base::TimeDelta& timeout) {
// For the moment, still only test linking shaders. TestShaderComponent component = base::RandInt(0, 1)
TestShaderComponent component = TestShaderComponent::kLink; ? TestShaderComponent::kLink
: TestShaderComponent::kCompile;
// The metallib listed above is in MTLLanguageVersion2_1, which is available // The metallib listed above is in MTLLanguageVersion2_1, which is available
// only on 10.14 and above. // only on 10.14 and above.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment