vkd3d-proton/tests/d3d12_raytracing.c

2884 lines
189 KiB
C

/*
* Copyright 2016-2017 Józef Kucia for CodeWeavers
* Copyright 2020-2021 Philip Rebohle for Valve Corporation
* Copyright 2020-2021 Joshua Ashton for Valve Corporation
* Copyright 2020-2021 Hans-Kristian Arntzen for Valve Corporation
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#define VKD3D_DBG_CHANNEL VKD3D_DBG_CHANNEL_API
#include "d3d12_crosstest.h"
struct raytracing_test_context
{
struct test_context context;
ID3D12Device5 *device5;
ID3D12GraphicsCommandList4 *list4;
};
static void destroy_raytracing_test_context(struct raytracing_test_context *context)
{
ID3D12Device5_Release(context->device5);
ID3D12GraphicsCommandList4_Release(context->list4);
destroy_test_context(&context->context);
}
static bool init_raytracing_test_context(struct raytracing_test_context *context, D3D12_RAYTRACING_TIER tier)
{
if (!init_compute_test_context(&context->context))
return false;
if (!context_supports_dxil(&context->context))
{
destroy_test_context(&context->context);
return false;
}
if (FAILED(ID3D12Device_QueryInterface(context->context.device, &IID_ID3D12Device5, (void**)&context->device5)))
{
skip("ID3D12Device5 is not supported. Skipping RT test.\n");
destroy_test_context(&context->context);
return false;
}
if (FAILED(ID3D12GraphicsCommandList_QueryInterface(context->context.list, &IID_ID3D12GraphicsCommandList4, (void**)&context->list4)))
{
skip("ID3D12GraphicsCommandList4 is not supported. Skipping RT test.\n");
ID3D12Device5_Release(context->device5);
destroy_test_context(&context->context);
return false;
}
{
D3D12_FEATURE_DATA_D3D12_OPTIONS5 opts5;
if (FAILED(ID3D12Device5_CheckFeatureSupport(context->device5, D3D12_FEATURE_D3D12_OPTIONS5, &opts5, sizeof(opts5))) ||
opts5.RaytracingTier < tier)
{
skip("Raytracing tier #%x is not supported on this device. Skipping RT test.\n", tier);
ID3D12Device5_Release(context->device5);
ID3D12GraphicsCommandList4_Release(context->list4);
destroy_test_context(&context->context);
return false;
}
}
return true;
}
static D3D12_SHADER_BYTECODE get_rayquery_shader(void)
{
static const BYTE rt_code_dxil[] =
{
#if 0
RaytracingAccelerationStructure AS : register(t0);
StructuredBuffer<float2> RayPositions : register(t1);
RWStructuredBuffer<float2> Buf : register(u0);
cbuffer Flags : register(b0, space0)
{
float2 miss_color;
uint flags;
};
[numthreads(64, 1, 1)]
void main(uint index : SV_DispatchThreadID)
{
float2 color = float2(0.0, 0.0);
RayDesc ray;
ray.Origin = float3(RayPositions[index], 1.0);
ray.Direction = float3(0.0, 0.0, -1.0);
ray.TMin = 0;
ray.TMax = 10;
RayQuery<RAY_FLAG_NONE> rq;
rq.TraceRayInline(AS, flags, 0x01, ray);
while (rq.Proceed())
{
if (rq.CandidateType() == CANDIDATE_NON_OPAQUE_TRIANGLE)
{
// Synthesize any-hit shader.
color.x += 1.0f;
// Ignore hit, don't commit.
// Just test that this doesn't screw up anything.
rq.Abort();
}
else
{
// Synthesize intersection shader, generate hit at 1.0f.
// Synthesize any-hit shader and skip it, otherwise, commit.
if (rq.CandidateProceduralPrimitiveNonOpaque())
color.y += 1.0f;
else if (1.0f < rq.CommittedRayT())
rq.CommitProceduralPrimitiveHit(1.0f);
}
}
if (rq.CommittedStatus() == COMMITTED_NOTHING)
{
// Synthesize miss shader.
color += miss_color;
}
else
{
// Synthesize closest hit shader.
uint hit_group_index = rq.CommittedInstanceContributionToHitGroupIndex();
hit_group_index += rq.CommittedGeometryIndex();
color += float2(hit_group_index + 1, hit_group_index + 2);
}
Buf[index] = color;
}
#endif
0x44, 0x58, 0x42, 0x43, 0x87, 0xb0, 0x7e, 0x92, 0x30, 0xe0, 0x59, 0x6f, 0x2a, 0xde, 0xe2, 0xa3, 0x26, 0x45, 0xd7, 0x96, 0x01, 0x00, 0x00, 0x00, 0xf4, 0x0a, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
0x38, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0x18, 0x01, 0x00, 0x00, 0x34, 0x01, 0x00, 0x00, 0x53, 0x46, 0x49, 0x30, 0x08, 0x00, 0x00, 0x00,
0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x53, 0x47, 0x31, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x4f, 0x53, 0x47, 0x31, 0x08, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x50, 0x53, 0x56, 0x30, 0xa8, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x41, 0x53, 0x48, 0x14, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x09, 0xf1, 0x28, 0x8b, 0x62, 0xef, 0x18, 0x39, 0xb8, 0x39, 0x0d, 0xc4, 0x1f, 0x7d, 0x96, 0xaa, 0x44, 0x58, 0x49, 0x4c, 0xb8, 0x09, 0x00, 0x00, 0x65, 0x00, 0x05, 0x00,
0x6e, 0x02, 0x00, 0x00, 0x44, 0x58, 0x49, 0x4c, 0x05, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0xa0, 0x09, 0x00, 0x00, 0x42, 0x43, 0xc0, 0xde, 0x21, 0x0c, 0x00, 0x00, 0x65, 0x02, 0x00, 0x00,
0x0b, 0x82, 0x20, 0x00, 0x02, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x07, 0x81, 0x23, 0x91, 0x41, 0xc8, 0x04, 0x49, 0x06, 0x10, 0x32, 0x39, 0x92, 0x01, 0x84, 0x0c, 0x25, 0x05, 0x08, 0x19,
0x1e, 0x04, 0x8b, 0x62, 0x80, 0x18, 0x45, 0x02, 0x42, 0x92, 0x0b, 0x42, 0xc4, 0x10, 0x32, 0x14, 0x38, 0x08, 0x18, 0x4b, 0x0a, 0x32, 0x62, 0x88, 0x48, 0x90, 0x14, 0x20, 0x43, 0x46, 0x88, 0xa5,
0x00, 0x19, 0x32, 0x42, 0xe4, 0x48, 0x0e, 0x90, 0x11, 0x23, 0xc4, 0x50, 0x41, 0x51, 0x81, 0x8c, 0xe1, 0x83, 0xe5, 0x8a, 0x04, 0x31, 0x46, 0x06, 0x51, 0x18, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
0x1b, 0x8c, 0xe0, 0xff, 0xff, 0xff, 0xff, 0x07, 0x40, 0x02, 0xa8, 0x0d, 0x84, 0xf0, 0xff, 0xff, 0xff, 0xff, 0x03, 0x20, 0x6d, 0x30, 0x86, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x09, 0xa8, 0x00,
0x49, 0x18, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x13, 0x82, 0x60, 0x42, 0x20, 0x4c, 0x08, 0x06, 0x00, 0x00, 0x00, 0x00, 0x89, 0x20, 0x00, 0x00, 0x63, 0x00, 0x00, 0x00, 0x32, 0x22, 0x88, 0x09,
0x20, 0x64, 0x85, 0x04, 0x13, 0x23, 0xa4, 0x84, 0x04, 0x13, 0x23, 0xe3, 0x84, 0xa1, 0x90, 0x14, 0x12, 0x4c, 0x8c, 0x8c, 0x0b, 0x84, 0xc4, 0x4c, 0x10, 0xb8, 0xc1, 0x08, 0x40, 0x09, 0x00, 0x0a,
0xe6, 0x08, 0xc0, 0xa0, 0x0c, 0xc3, 0x30, 0x10, 0x31, 0x47, 0x80, 0x90, 0x71, 0xcf, 0x70, 0xf9, 0x13, 0xf6, 0x10, 0x92, 0x1f, 0x02, 0xcd, 0xb0, 0x10, 0x28, 0x38, 0x66, 0x00, 0xca, 0x02, 0x0c,
0xc8, 0x30, 0x24, 0x49, 0x92, 0x18, 0x03, 0x29, 0x37, 0x0d, 0x97, 0x3f, 0x61, 0x0f, 0x21, 0xf9, 0x2b, 0x21, 0xad, 0xc4, 0xe4, 0x17, 0xb7, 0x8d, 0x8a, 0x24, 0x49, 0x92, 0xa1, 0x1c, 0xcc, 0x80,
0x0c, 0x83, 0x31, 0x50, 0x73, 0xd4, 0x70, 0xf9, 0x13, 0xf6, 0x10, 0x92, 0xcf, 0x6d, 0x54, 0xb1, 0x12, 0x93, 0x8f, 0xdc, 0x36, 0x22, 0x86, 0x61, 0x18, 0x0a, 0xf1, 0x0c, 0xc8, 0x40, 0xd0, 0x51,
0xc3, 0xe5, 0x4f, 0xd8, 0x43, 0x48, 0x3e, 0xb7, 0x51, 0xc5, 0x4a, 0x4c, 0x7e, 0x71, 0xdb, 0x88, 0x48, 0x92, 0x24, 0x29, 0x84, 0x34, 0x20, 0x03, 0x4d, 0xc5, 0x01, 0x86, 0x01, 0x19, 0x86, 0x24,
0x49, 0x92, 0x24, 0x49, 0x12, 0xaa, 0x0a, 0x01, 0x0c, 0x43, 0x42, 0x57, 0x19, 0x92, 0x61, 0xa0, 0x6c, 0x8e, 0x20, 0x28, 0xc3, 0x36, 0x0c, 0xc4, 0x95, 0x01, 0x18, 0x06, 0xf2, 0x8a, 0x81, 0x0c,
0xc6, 0x30, 0x6c, 0x04, 0x0e, 0x04, 0x9c, 0x19, 0x48, 0x53, 0x44, 0x09, 0x93, 0xbf, 0x02, 0xd8, 0x14, 0x01, 0x02, 0xd2, 0x18, 0x9a, 0x20, 0x10, 0x0b, 0x11, 0x01, 0x13, 0xe2, 0x34, 0xec, 0x14,
0x51, 0xc2, 0x44, 0x45, 0x04, 0x0a, 0x06, 0x1a, 0x87, 0x11, 0x84, 0x64, 0xa6, 0x34, 0x18, 0x07, 0x76, 0x08, 0x87, 0x79, 0x98, 0x07, 0x37, 0x98, 0x05, 0x7a, 0x90, 0x87, 0x7a, 0x18, 0x07, 0x7a,
0xa8, 0x07, 0x79, 0x28, 0x07, 0x72, 0x10, 0x85, 0x7a, 0x30, 0x07, 0x73, 0x28, 0x07, 0x79, 0xe0, 0x03, 0x7b, 0x28, 0x87, 0x71, 0xa0, 0x87, 0x77, 0x90, 0x07, 0x3e, 0x30, 0x07, 0x76, 0x78, 0x87,
0x70, 0xa0, 0x07, 0x36, 0x00, 0x03, 0x39, 0xf0, 0x03, 0x30, 0xf0, 0x03, 0x14, 0x94, 0x64, 0xce, 0xb4, 0x06, 0xe3, 0xc0, 0x0e, 0xe1, 0x30, 0x0f, 0xf3, 0xe0, 0x06, 0xb2, 0x70, 0x0b, 0xb3, 0x40,
0x0f, 0xf2, 0x50, 0x0f, 0xe3, 0x40, 0x0f, 0xf5, 0x20, 0x0f, 0xe5, 0x40, 0x0e, 0xa2, 0x50, 0x0f, 0xe6, 0x60, 0x0e, 0xe5, 0x20, 0x0f, 0x7c, 0x60, 0x0f, 0xe5, 0x30, 0x0e, 0xf4, 0xf0, 0x0e, 0xf2,
0xc0, 0x07, 0xe6, 0xc0, 0x0e, 0xef, 0x10, 0x0e, 0xf4, 0xc0, 0x06, 0x60, 0x20, 0x07, 0x7e, 0x00, 0x06, 0x7e, 0x80, 0x82, 0x92, 0xd0, 0x2b, 0xbe, 0x05, 0x30, 0x24, 0x24, 0x94, 0x03, 0xa9, 0x73,
0x04, 0xa0, 0x30, 0x05, 0x00, 0x00, 0x00, 0x00, 0x13, 0x14, 0x72, 0xc0, 0x87, 0x74, 0x60, 0x87, 0x36, 0x68, 0x87, 0x79, 0x68, 0x03, 0x72, 0xc0, 0x87, 0x0d, 0xaf, 0x50, 0x0e, 0x6d, 0xd0, 0x0e,
0x7a, 0x50, 0x0e, 0x6d, 0x00, 0x0f, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x71, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x78, 0xa0, 0x07, 0x73, 0x20,
0x07, 0x6d, 0x90, 0x0e, 0x71, 0x60, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, 0xe9, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74,
0xd0, 0x06, 0xe6, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x60, 0x0e, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, 0xe6, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07,
0x6d, 0xe0, 0x0e, 0x78, 0xa0, 0x07, 0x71, 0x60, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x43, 0x9e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86,
0x3c, 0x04, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x79, 0x14, 0x20, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xf2, 0x34, 0x40, 0x00, 0x0c, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0xe4, 0x81, 0x80, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0xc8, 0x33, 0x01, 0x01, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xc0, 0x90, 0x87, 0x00, 0x02, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x21, 0x0f, 0x01, 0x04, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43, 0x9e, 0x0a, 0x08, 0x00,
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86, 0x3c, 0x17, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x79, 0x32, 0x20, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x18, 0xf2, 0x70, 0x40, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0xe4, 0xe1, 0x80, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0xc8, 0xe3, 0x01,
0x01, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x90, 0x07, 0x0c, 0x80, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x0b, 0x04, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00,
0x32, 0x1e, 0x98, 0x14, 0x19, 0x11, 0x4c, 0x90, 0x8c, 0x09, 0x26, 0x47, 0xc6, 0x04, 0x43, 0x1a, 0x4a, 0xa0, 0x14, 0x8a, 0x61, 0x04, 0xa0, 0x40, 0x0a, 0xa1, 0x30, 0x0a, 0xa2, 0x00, 0x03, 0x68,
0x1b, 0x01, 0x20, 0xb6, 0x40, 0x01, 0x01, 0x41, 0xe8, 0x9c, 0x01, 0xa0, 0x74, 0x06, 0x80, 0xd6, 0x19, 0x00, 0x22, 0x67, 0x00, 0x00, 0x00, 0x00, 0x79, 0x18, 0x00, 0x00, 0x4b, 0x00, 0x00, 0x00,
0x1a, 0x03, 0x4c, 0x90, 0x46, 0x02, 0x13, 0x44, 0x35, 0x18, 0x63, 0x0b, 0x73, 0x3b, 0x03, 0xb1, 0x2b, 0x93, 0x9b, 0x4b, 0x7b, 0x73, 0x03, 0x99, 0x71, 0xb9, 0x01, 0x41, 0xa1, 0x0b, 0x3b, 0x9b,
0x7b, 0x91, 0x2a, 0x62, 0x2a, 0x0a, 0x9a, 0x2a, 0xfa, 0x9a, 0xb9, 0x81, 0x79, 0x31, 0x4b, 0x73, 0x0b, 0x63, 0x4b, 0xd9, 0x10, 0x04, 0x13, 0x84, 0xe1, 0x99, 0x20, 0x0c, 0xd0, 0x06, 0x61, 0x20,
0x26, 0x08, 0x43, 0xb4, 0x41, 0x18, 0x0c, 0x0a, 0x63, 0x73, 0x1b, 0x06, 0xc4, 0x20, 0x26, 0x08, 0x83, 0x34, 0x41, 0x20, 0x83, 0x8e, 0xc0, 0x04, 0x61, 0x98, 0x26, 0x08, 0x03, 0xb5, 0x41, 0x50,
0x9c, 0x0d, 0x89, 0xb2, 0x30, 0x8a, 0x32, 0x34, 0xca, 0x33, 0x41, 0x38, 0x03, 0x6d, 0x82, 0x30, 0x54, 0x13, 0x84, 0xc1, 0xda, 0x20, 0x0c, 0xd3, 0x86, 0x64, 0x88, 0x18, 0x65, 0x18, 0x24, 0x85,
0xda, 0x20, 0x40, 0xd5, 0x04, 0x21, 0x0d, 0xb6, 0x09, 0xc2, 0x86, 0x6d, 0x58, 0x94, 0x8b, 0x51, 0x94, 0x41, 0xc2, 0x30, 0x8c, 0xda, 0x10, 0x64, 0x13, 0x84, 0x35, 0xe0, 0x36, 0x20, 0xca, 0xc6,
0x28, 0xca, 0x20, 0x01, 0x1b, 0x02, 0x6e, 0x03, 0x61, 0x69, 0x1d, 0x30, 0x41, 0x10, 0x00, 0x12, 0x6d, 0x61, 0x69, 0x6e, 0x13, 0x04, 0x36, 0xc8, 0x26, 0x08, 0xc3, 0xb5, 0x61, 0x10, 0x83, 0x61,
0xd8, 0x40, 0x28, 0x61, 0xe0, 0x8c, 0xc1, 0x86, 0xe2, 0x03, 0x03, 0xc0, 0x23, 0x83, 0x2a, 0x6c, 0x6c, 0x76, 0x6d, 0x2e, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x53, 0x82, 0xa0, 0x0a, 0x19, 0x9e, 0x8b,
0x5d, 0x99, 0xdc, 0x5c, 0xda, 0x9b, 0xdb, 0x94, 0x80, 0x68, 0x42, 0x86, 0xe7, 0x62, 0x17, 0xc6, 0x66, 0x57, 0x26, 0x37, 0x25, 0x30, 0xea, 0x90, 0xe1, 0xb9, 0xcc, 0xa1, 0x85, 0x91, 0x95, 0xc9,
0x35, 0xbd, 0x91, 0x95, 0xb1, 0x4d, 0x09, 0x90, 0x32, 0x64, 0x78, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x53, 0x82, 0xae, 0x0e, 0x19, 0x9e, 0x4b, 0x99, 0x1b, 0x9d, 0x5c,
0x1e, 0xd4, 0x5b, 0x9a, 0x1b, 0xdd, 0xdc, 0x94, 0x80, 0x0c, 0x00, 0x00, 0x79, 0x18, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00, 0x33, 0x08, 0x80, 0x1c, 0xc4, 0xe1, 0x1c, 0x66, 0x14, 0x01, 0x3d, 0x88,
0x43, 0x38, 0x84, 0xc3, 0x8c, 0x42, 0x80, 0x07, 0x79, 0x78, 0x07, 0x73, 0x98, 0x71, 0x0c, 0xe6, 0x00, 0x0f, 0xed, 0x10, 0x0e, 0xf4, 0x80, 0x0e, 0x33, 0x0c, 0x42, 0x1e, 0xc2, 0xc1, 0x1d, 0xce,
0xa1, 0x1c, 0x66, 0x30, 0x05, 0x3d, 0x88, 0x43, 0x38, 0x84, 0x83, 0x1b, 0xcc, 0x03, 0x3d, 0xc8, 0x43, 0x3d, 0x8c, 0x03, 0x3d, 0xcc, 0x78, 0x8c, 0x74, 0x70, 0x07, 0x7b, 0x08, 0x07, 0x79, 0x48,
0x87, 0x70, 0x70, 0x07, 0x7a, 0x70, 0x03, 0x76, 0x78, 0x87, 0x70, 0x20, 0x87, 0x19, 0xcc, 0x11, 0x0e, 0xec, 0x90, 0x0e, 0xe1, 0x30, 0x0f, 0x6e, 0x30, 0x0f, 0xe3, 0xf0, 0x0e, 0xf0, 0x50, 0x0e,
0x33, 0x10, 0xc4, 0x1d, 0xde, 0x21, 0x1c, 0xd8, 0x21, 0x1d, 0xc2, 0x61, 0x1e, 0x66, 0x30, 0x89, 0x3b, 0xbc, 0x83, 0x3b, 0xd0, 0x43, 0x39, 0xb4, 0x03, 0x3c, 0xbc, 0x83, 0x3c, 0x84, 0x03, 0x3b,
0xcc, 0xf0, 0x14, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x68, 0x87, 0x72, 0x68, 0x07, 0x37, 0x80, 0x87, 0x70, 0x90, 0x87, 0x70, 0x60, 0x07, 0x76, 0x28, 0x07, 0x76, 0xf8, 0x05, 0x76, 0x78,
0x87, 0x77, 0x80, 0x87, 0x5f, 0x08, 0x87, 0x71, 0x18, 0x87, 0x72, 0x98, 0x87, 0x79, 0x98, 0x81, 0x2c, 0xee, 0xf0, 0x0e, 0xee, 0xe0, 0x0e, 0xf5, 0xc0, 0x0e, 0xec, 0x30, 0x03, 0x62, 0xc8, 0xa1,
0x1c, 0xe4, 0xa1, 0x1c, 0xcc, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xdc, 0x61, 0x1c, 0xca, 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca, 0x61, 0x06, 0xd6, 0x90, 0x43, 0x39, 0xc8, 0x43, 0x39, 0x98, 0x43, 0x39,
0xc8, 0x43, 0x39, 0xb8, 0xc3, 0x38, 0x94, 0x43, 0x38, 0x88, 0x03, 0x3b, 0x94, 0xc3, 0x2f, 0xbc, 0x83, 0x3c, 0xfc, 0x82, 0x3b, 0xd4, 0x03, 0x3b, 0xb0, 0xc3, 0x0c, 0xc4, 0x21, 0x07, 0x7c, 0x70,
0x03, 0x7a, 0x28, 0x87, 0x76, 0x80, 0x87, 0x19, 0xd1, 0x43, 0x0e, 0xf8, 0xe0, 0x06, 0xe4, 0x20, 0x0e, 0xe7, 0xe0, 0x06, 0xf6, 0x10, 0x0e, 0xf2, 0xc0, 0x0e, 0xe1, 0x90, 0x0f, 0xef, 0x50, 0x0f,
0xf4, 0x30, 0x83, 0x81, 0xc8, 0x01, 0x1f, 0xdc, 0x40, 0x1c, 0xe4, 0xa1, 0x1c, 0xc2, 0x61, 0x1d, 0xdc, 0x40, 0x1c, 0xe4, 0x01, 0x00, 0x00, 0x00, 0x71, 0x20, 0x00, 0x00, 0x4e, 0x00, 0x00, 0x00,
0x76, 0x60, 0x0d, 0x97, 0xef, 0x3c, 0x3e, 0xb0, 0x2c, 0x8e, 0x00, 0x4c, 0xc4, 0x0a, 0x60, 0x2a, 0x45, 0x44, 0x98, 0x15, 0x6c, 0xc3, 0xe5, 0x3b, 0x8f, 0x2f, 0x04, 0x54, 0x51, 0x10, 0x51, 0xe9,
0x00, 0x43, 0x49, 0x18, 0x80, 0x80, 0xf9, 0xc5, 0x6d, 0x1b, 0xc1, 0x36, 0x5c, 0xbe, 0xf3, 0xf8, 0x42, 0x40, 0x15, 0x05, 0x11, 0x95, 0x0e, 0x30, 0x94, 0x84, 0x01, 0x08, 0x98, 0x8f, 0xdc, 0xb6,
0x39, 0x48, 0xc3, 0xe5, 0x3b, 0x8f, 0x2f, 0x44, 0x04, 0x30, 0x11, 0x21, 0xd0, 0x0c, 0x0b, 0x61, 0x03, 0xd7, 0x70, 0xf9, 0xce, 0xe3, 0x47, 0x80, 0xb5, 0x51, 0x45, 0x41, 0x44, 0xa5, 0x03, 0x0c,
0x7e, 0x71, 0xdb, 0x26, 0x80, 0x0d, 0x97, 0xef, 0x3c, 0x7e, 0x04, 0x58, 0x1b, 0x55, 0x14, 0x44, 0xc4, 0x4e, 0x4e, 0x44, 0xf8, 0xc5, 0x6d, 0x5b, 0x03, 0x35, 0x5c, 0xbe, 0xf3, 0xf8, 0x11, 0x80,
0xa9, 0x14, 0x11, 0x61, 0xbf, 0x16, 0x38, 0xd1, 0x64, 0x09, 0x6b, 0x30, 0x5c, 0xbe, 0xf3, 0xf8, 0x11, 0x80, 0xa9, 0x14, 0x11, 0x61, 0x3f, 0xe7, 0x30, 0x0c, 0x32, 0xa5, 0x91, 0x23, 0x10, 0x03,
0x15, 0x01, 0x4b, 0x1a, 0x21, 0x0c, 0x32, 0x21, 0x15, 0x11, 0x22, 0x93, 0x2d, 0x64, 0xc3, 0xe5, 0x3b, 0x8f, 0x1f, 0x01, 0x98, 0x4a, 0x11, 0x11, 0xf6, 0xa7, 0x91, 0x23, 0x10, 0xc4, 0xe0, 0x23,
0xb5, 0x29, 0x78, 0xc3, 0xe5, 0x3b, 0x8f, 0x1f, 0x01, 0x98, 0x4a, 0x11, 0x11, 0xf6, 0xb3, 0x13, 0x30, 0x11, 0xac, 0x00, 0x2c, 0x40, 0xe4, 0x17, 0xb7, 0x6d, 0x0c, 0xdd, 0x70, 0xf9, 0xce, 0xe3,
0x47, 0x00, 0xa6, 0x52, 0x44, 0x84, 0xfd, 0xec, 0x04, 0x4c, 0x04, 0x2b, 0x00, 0x0b, 0x10, 0xf9, 0x48, 0x6d, 0x06, 0xde, 0x70, 0xf9, 0xce, 0xe3, 0x47, 0x00, 0xa6, 0x52, 0x44, 0x84, 0xfd, 0xec,
0x04, 0x4c, 0x04, 0x2b, 0x00, 0x0b, 0x10, 0xf9, 0xc8, 0x6d, 0x1b, 0x42, 0x37, 0x5c, 0xbe, 0xf3, 0xf8, 0x11, 0x80, 0xa9, 0x14, 0x11, 0x61, 0x7f, 0x1b, 0x01, 0x02, 0xb1, 0x02, 0x98, 0xd8, 0x2c,
0x48, 0x43, 0x58, 0x80, 0x34, 0x5c, 0xbe, 0xf3, 0xf8, 0xd3, 0x11, 0x11, 0xc0, 0x20, 0x0e, 0x3e, 0x72, 0xdb, 0x06, 0x40, 0x30, 0x00, 0xd2, 0x00, 0x61, 0x20, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00,
0x13, 0x04, 0x4e, 0x2c, 0x10, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x34, 0x94, 0x5c, 0xd9, 0x15, 0xba, 0x40, 0xe9, 0x06, 0x94, 0xa5, 0x40, 0x91, 0x0b, 0x94, 0xb9, 0x40, 0xc9, 0x0b, 0x94,
0xba, 0x40, 0xf1, 0x0b, 0x14, 0xe4, 0x40, 0xb9, 0x0b, 0x14, 0xbc, 0x40, 0xb9, 0x0e, 0x94, 0xe8, 0x40, 0x11, 0x14, 0xa6, 0x00, 0x19, 0x23, 0x00, 0x65, 0x50, 0x02, 0x45, 0x40, 0xc9, 0x08, 0xc0,
0x18, 0x01, 0x08, 0x82, 0x20, 0xfe, 0xcd, 0x00, 0x8c, 0x11, 0x80, 0x20, 0x08, 0xe2, 0xbf, 0x30, 0x46, 0x00, 0x82, 0x20, 0x28, 0x83, 0x01, 0x00, 0x23, 0x06, 0x09, 0x00, 0x82, 0x60, 0x00, 0x06,
0x6a, 0xa0, 0x1d, 0x66, 0x60, 0x06, 0x60, 0x30, 0x62, 0x90, 0x00, 0x20, 0x08, 0x06, 0x60, 0xb0, 0x06, 0x9b, 0xa2, 0x06, 0x6a, 0x10, 0x06, 0x23, 0x06, 0x09, 0x00, 0x82, 0x60, 0x00, 0x06, 0x6c,
0xc0, 0x2d, 0x68, 0x80, 0x06, 0x62, 0x30, 0x62, 0x90, 0x00, 0x20, 0x08, 0x06, 0x60, 0xd0, 0x06, 0x5d, 0x92, 0x06, 0x69, 0x30, 0x06, 0x23, 0x06, 0x06, 0x00, 0x82, 0x60, 0x40, 0xec, 0xc1, 0xa6,
0x06, 0x23, 0x06, 0x0a, 0x00, 0x82, 0x60, 0xd0, 0xe8, 0xc1, 0x46, 0x04, 0x6b, 0xd0, 0xa4, 0xc1, 0x68, 0x42, 0x00, 0x8c, 0x26, 0x08, 0xc1, 0x88, 0x81, 0x01, 0x80, 0x20, 0x18, 0x10, 0x79, 0xd0,
0xb9, 0xc1, 0x88, 0xc1, 0x01, 0x80, 0x20, 0x18, 0x40, 0x7d, 0x20, 0x06, 0xc6, 0x1b, 0x8c, 0x26, 0x04, 0xc2, 0x88, 0x41, 0x04, 0x80, 0x20, 0x18, 0x54, 0x7b, 0xf0, 0x0d, 0x49, 0x40, 0x07, 0x05,
0xf1, 0x40, 0x10, 0xd4, 0x30, 0x23, 0x06, 0x06, 0x00, 0x82, 0x60, 0xc0, 0xe1, 0xc1, 0x18, 0x0c, 0xb3, 0x0c, 0x81, 0x12, 0xcc, 0x12, 0x08, 0x03, 0x15, 0xc9, 0x63, 0x88, 0x41, 0x30, 0x50, 0x91,
0x3c, 0x06, 0x19, 0x04, 0x23, 0x06, 0x06, 0x00, 0x82, 0x60, 0x40, 0x80, 0x42, 0x18, 0x18, 0xc3, 0x0d, 0x41, 0x1d, 0x80, 0xc1, 0x2c, 0xc3, 0x40, 0x04, 0x46, 0x50, 0xf0, 0x19, 0x31, 0x30, 0x00,
0x10, 0x04, 0x03, 0x8f, 0x0f, 0xc6, 0x20, 0x99, 0x25, 0x30, 0x46, 0x0c, 0x0c, 0x00, 0x04, 0xc1, 0x80, 0xeb, 0x03, 0x31, 0x48, 0x66, 0x19, 0x8a, 0x23, 0xb0, 0xc2, 0x82, 0xcf, 0x2c, 0x81, 0x31,
0x50, 0x92, 0x18, 0x83, 0x53, 0x38, 0x88, 0x73, 0x0c, 0x94, 0x24, 0xce, 0x40, 0x14, 0x0e, 0xe2, 0x1c, 0x23, 0x06, 0x06, 0x00, 0x82, 0x60, 0xc0, 0x89, 0x42, 0x1b, 0x34, 0xb3, 0x0c, 0x42, 0x12,
0x8c, 0x18, 0x18, 0x00, 0x08, 0x82, 0x41, 0x46, 0x0a, 0x66, 0xe0, 0x0c, 0x47, 0x04, 0x9b, 0xf0, 0xcd, 0x32, 0x20, 0x46, 0x30, 0x62, 0x70, 0x00, 0x20, 0x08, 0x06, 0xd7, 0x29, 0x9c, 0x01, 0xc4,
0xcd, 0x12, 0x18, 0xb3, 0x04, 0xca, 0x40, 0x45, 0xa2, 0x07, 0x80, 0x92, 0x0c, 0x54, 0x24, 0x7c, 0x00, 0x28, 0xc9, 0x88, 0x81, 0x01, 0x80, 0x20, 0x18, 0x10, 0xac, 0x80, 0x06, 0xd2, 0x70, 0x43,
0x10, 0x0a, 0x60, 0x30, 0xcb, 0xb0, 0x30, 0xc1, 0x88, 0xc1, 0x01, 0x80, 0x20, 0x18, 0x4c, 0xaf, 0x50, 0x07, 0x99, 0x28, 0x8c, 0x26, 0x04, 0xc0, 0x68, 0x82, 0x10, 0xcc, 0x12, 0x34, 0x23, 0x06,
0x06, 0x00, 0x82, 0x60, 0x40, 0xc4, 0x02, 0x1b, 0x5c, 0x23, 0x06, 0x06, 0x00, 0x82, 0x60, 0x40, 0xc8, 0x02, 0x1b, 0x60, 0x15, 0x08, 0x50, 0xc1, 0x2a, 0xc0, 0x05, 0x49, 0xd5, 0xf0, 0x06, 0x70,
0x41, 0x52, 0xb3, 0x04, 0xcd, 0x40, 0x45, 0x22, 0x2d, 0x06, 0x33, 0x50, 0x91, 0x48, 0x0b, 0xc1, 0x98, 0x00, 0xc1, 0xc7, 0x04, 0x08, 0x3e, 0x23, 0x06, 0x0e, 0x00, 0x82, 0x60, 0xa0, 0x80, 0x03,
0x1d, 0xa8, 0x81, 0x19, 0xc0, 0x82, 0x10, 0xb4, 0x41, 0x1b, 0xc8, 0x81, 0x2b, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
D3D12_SHADER_BYTECODE code;
code.pShaderBytecode = rt_code_dxil;
code.BytecodeLength = sizeof(rt_code_dxil);
return code;
}
static D3D12_SHADER_BYTECODE get_static_sampler_rt_lib(void)
{
static const BYTE rt_lib_dxil[] =
{
#if 0
RaytracingAccelerationStructure AS : register(t0);
RWStructuredBuffer<float> Buf : register(u0);
Texture2D<float> Tex : register(t1);
SamplerState ClampSampler : register(s0);
SamplerState WrapSampler : register(s1);
SamplerState ClampWrapSampler : register(s2);
struct RayPayload
{
float value;
};
[shader("closesthit")]
void RayClosest1(inout RayPayload payload, BuiltInTriangleIntersectionAttributes attrib)
{
/* Tex(1, 1) + Tex(1, 0) = 40 + 20 = 60 */
payload.value =
Tex.SampleLevel(ClampSampler, 1.25.xx, 0.0) +
Tex.SampleLevel(ClampWrapSampler, 1.25.xx, 0.0);
}
[shader("closesthit")]
void RayClosest2(inout RayPayload payload, BuiltInTriangleIntersectionAttributes attrib)
{
/* Tex(0, 0) + Tex(1, 0) = 10 + 20 = 30 */
payload.value =
Tex.SampleLevel(WrapSampler, 1.25.xx, 0.0) +
Tex.SampleLevel(ClampWrapSampler, 1.25.xx, 0.0);
}
[shader("miss")]
void RayMiss(inout RayPayload payload)
{
payload.value = -1.0;
}
[shader("raygeneration")]
void RayGen()
{
RayPayload payload;
payload.value = 0.0;
uint2 index = DispatchRaysIndex().xy;
RayDesc ray;
ray.Origin = float3(10.0 * float2(index), 1.0);
ray.Direction = float3(0.0, 0.0, -1.0);
ray.TMin = 0;
ray.TMax = 10;
TraceRay(AS, RAY_FLAG_NONE, 1, 0, 1, 0, ray, payload);
Buf[index.y * 2 + index.x] = payload.value;
}
#endif
0x44, 0x58, 0x42, 0x43, 0x23, 0xb5, 0xe2, 0x67, 0x26, 0x4b, 0xc9, 0x4f, 0x2e, 0xe6, 0xd2, 0x8f, 0x3e, 0xbb, 0x32, 0x03, 0x01, 0x00, 0x00, 0x00, 0x0c, 0x12, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
0x30, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x4c, 0x03, 0x00, 0x00, 0x68, 0x03, 0x00, 0x00, 0x53, 0x46, 0x49, 0x30, 0x08, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x52, 0x44, 0x41, 0x54, 0x04, 0x03, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x40, 0x01, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 0xd0, 0x02, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x20, 0x01, 0x00, 0x00, 0x00, 0x43, 0x6c, 0x61, 0x6d, 0x70, 0x53, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x72, 0x00, 0x57, 0x72, 0x61, 0x70, 0x53, 0x61, 0x6d, 0x70, 0x6c, 0x65,
0x72, 0x00, 0x43, 0x6c, 0x61, 0x6d, 0x70, 0x57, 0x72, 0x61, 0x70, 0x53, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x72, 0x00, 0x41, 0x53, 0x00, 0x54, 0x65, 0x78, 0x00, 0x42, 0x75, 0x66, 0x00, 0x01, 0x3f,
0x52, 0x61, 0x79, 0x43, 0x6c, 0x6f, 0x73, 0x65, 0x73, 0x74, 0x31, 0x40, 0x40, 0x59, 0x41, 0x58, 0x55, 0x52, 0x61, 0x79, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x40, 0x40, 0x55, 0x42, 0x75,
0x69, 0x6c, 0x74, 0x49, 0x6e, 0x54, 0x72, 0x69, 0x61, 0x6e, 0x67, 0x6c, 0x65, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75,
0x74, 0x65, 0x73, 0x40, 0x40, 0x40, 0x5a, 0x00, 0x52, 0x61, 0x79, 0x43, 0x6c, 0x6f, 0x73, 0x65, 0x73, 0x74, 0x31, 0x00, 0x01, 0x3f, 0x52, 0x61, 0x79, 0x43, 0x6c, 0x6f, 0x73, 0x65, 0x73, 0x74,
0x32, 0x40, 0x40, 0x59, 0x41, 0x58, 0x55, 0x52, 0x61, 0x79, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x40, 0x40, 0x55, 0x42, 0x75, 0x69, 0x6c, 0x74, 0x49, 0x6e, 0x54, 0x72, 0x69, 0x61, 0x6e,
0x67, 0x6c, 0x65, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x40, 0x40, 0x40, 0x5a, 0x00, 0x52, 0x61,
0x79, 0x43, 0x6c, 0x6f, 0x73, 0x65, 0x73, 0x74, 0x32, 0x00, 0x01, 0x3f, 0x52, 0x61, 0x79, 0x4d, 0x69, 0x73, 0x73, 0x40, 0x40, 0x59, 0x41, 0x58, 0x55, 0x52, 0x61, 0x79, 0x50, 0x61, 0x79, 0x6c,
0x6f, 0x61, 0x64, 0x40, 0x40, 0x40, 0x5a, 0x00, 0x52, 0x61, 0x79, 0x4d, 0x69, 0x73, 0x73, 0x00, 0x01, 0x3f, 0x52, 0x61, 0x79, 0x47, 0x65, 0x6e, 0x40, 0x40, 0x59, 0x41, 0x58, 0x58, 0x5a, 0x00,
0x52, 0x61, 0x79, 0x47, 0x65, 0x6e, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xc8, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00,
0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xb8, 0x00, 0x00, 0x00,
0x04, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x0a, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x60, 0x00, 0x0a, 0x00, 0x8c, 0x00, 0x00, 0x00, 0xd6, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
0xff, 0xff, 0xff, 0xff, 0x0a, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x60, 0x00, 0x0a, 0x00,
0xe2, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0b, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x60, 0x00, 0x0b, 0x00, 0x08, 0x01, 0x00, 0x00, 0x18, 0x01, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x63, 0x00, 0x07, 0x00, 0x02, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x48, 0x41, 0x53, 0x48, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0xe6, 0x0d, 0xd0, 0x80, 0x74, 0xce, 0xca,
0xcd, 0xb1, 0xdd, 0x56, 0xbf, 0x49, 0x71, 0x36, 0x44, 0x58, 0x49, 0x4c, 0x9c, 0x0e, 0x00, 0x00, 0x63, 0x00, 0x06, 0x00, 0xa7, 0x03, 0x00, 0x00, 0x44, 0x58, 0x49, 0x4c, 0x03, 0x01, 0x00, 0x00,
0x10, 0x00, 0x00, 0x00, 0x84, 0x0e, 0x00, 0x00, 0x42, 0x43, 0xc0, 0xde, 0x21, 0x0c, 0x00, 0x00, 0x9e, 0x03, 0x00, 0x00, 0x0b, 0x82, 0x20, 0x00, 0x02, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00,
0x07, 0x81, 0x23, 0x91, 0x41, 0xc8, 0x04, 0x49, 0x06, 0x10, 0x32, 0x39, 0x92, 0x01, 0x84, 0x0c, 0x25, 0x05, 0x08, 0x19, 0x1e, 0x04, 0x8b, 0x62, 0x80, 0x18, 0x45, 0x02, 0x42, 0x92, 0x0b, 0x42,
0xc4, 0x10, 0x32, 0x14, 0x38, 0x08, 0x18, 0x4b, 0x0a, 0x32, 0x62, 0x88, 0x48, 0x90, 0x14, 0x20, 0x43, 0x46, 0x88, 0xa5, 0x00, 0x19, 0x32, 0x42, 0xe4, 0x48, 0x0e, 0x90, 0x11, 0x23, 0xc4, 0x50,
0x41, 0x51, 0x81, 0x8c, 0xe1, 0x83, 0xe5, 0x8a, 0x04, 0x31, 0x46, 0x06, 0x51, 0x18, 0x00, 0x00, 0x5d, 0x00, 0x00, 0x00, 0x1b, 0x8c, 0x20, 0x00, 0x12, 0x60, 0xd9, 0x60, 0x08, 0x02, 0xb0, 0x00,
0xd4, 0x06, 0xf0, 0x18, 0xfe, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x24, 0x82, 0x1c, 0xd2, 0x61, 0x1e, 0xc2, 0x41, 0x1c, 0xd8, 0xa1, 0x1c, 0xda, 0x80, 0x1e, 0xc2, 0x21, 0x1d, 0xd8, 0xa1, 0x0d, 0xc6,
0x21, 0x1c, 0xd8, 0x81, 0x1d, 0xe6, 0x01, 0x30, 0x87, 0x70, 0x60, 0x87, 0x79, 0x28, 0x07, 0x80, 0x60, 0x87, 0x72, 0x98, 0x87, 0x79, 0x68, 0x03, 0x78, 0x90, 0x87, 0x72, 0x18, 0x87, 0x74, 0x98,
0x87, 0x72, 0x68, 0x03, 0x73, 0x80, 0x87, 0x76, 0x08, 0x07, 0x72, 0x00, 0xcc, 0x21, 0x1c, 0xd8, 0x61, 0x1e, 0xca, 0x01, 0x20, 0xdc, 0xe1, 0x1d, 0xda, 0xc0, 0x1c, 0xe4, 0x21, 0x1c, 0xda, 0xa1,
0x1c, 0xda, 0x00, 0x1e, 0xde, 0x21, 0x1d, 0xdc, 0x81, 0x1e, 0xca, 0x41, 0x1e, 0xda, 0xa0, 0x1c, 0xd8, 0x21, 0x1d, 0xda, 0x01, 0x30, 0x87, 0x70, 0x60, 0x87, 0x79, 0x28, 0x07, 0x80, 0x70, 0x87,
0x77, 0x68, 0x83, 0x74, 0x70, 0x07, 0x73, 0x98, 0x87, 0x36, 0x30, 0x07, 0x78, 0x68, 0x83, 0x76, 0x08, 0x07, 0x7a, 0x40, 0x07, 0xc0, 0x1c, 0xc2, 0x81, 0x1d, 0xe6, 0xa1, 0x1c, 0x00, 0xc2, 0x1d,
0xde, 0xa1, 0x0d, 0xdc, 0x21, 0x1c, 0xdc, 0x61, 0x1e, 0xda, 0xc0, 0x1c, 0xe0, 0xa1, 0x0d, 0xda, 0x21, 0x1c, 0xe8, 0x01, 0x1d, 0x00, 0x73, 0x08, 0x07, 0x76, 0x98, 0x87, 0x72, 0x00, 0x06, 0x77,
0x78, 0x87, 0x36, 0x90, 0x87, 0x72, 0x08, 0x07, 0x76, 0x48, 0x87, 0x73, 0x70, 0x87, 0x36, 0x98, 0x07, 0x7a, 0x08, 0x87, 0x71, 0x58, 0x07, 0x80, 0x98, 0x07, 0x7a, 0x08, 0x87, 0x71, 0x58, 0x87,
0x36, 0x80, 0x07, 0x79, 0x78, 0x07, 0x7a, 0x28, 0x87, 0x71, 0xa0, 0x87, 0x77, 0x90, 0x87, 0x36, 0x10, 0x87, 0x7a, 0x30, 0x07, 0x73, 0x28, 0x07, 0x79, 0x68, 0x83, 0x79, 0x48, 0x07, 0x7d, 0x28,
0x07, 0x00, 0x0e, 0x00, 0xa2, 0x1e, 0xdc, 0x61, 0x1e, 0xc2, 0xc1, 0x1c, 0xca, 0xa1, 0x0d, 0xcc, 0x01, 0x1e, 0xda, 0xa0, 0x1d, 0xc2, 0x81, 0x1e, 0xd0, 0x01, 0x30, 0x87, 0x70, 0x60, 0x87, 0x79,
0x28, 0x07, 0x80, 0xa8, 0x87, 0x79, 0x28, 0x87, 0x36, 0x98, 0x87, 0x77, 0x30, 0x07, 0x7a, 0x68, 0x03, 0x73, 0x60, 0x87, 0x77, 0x08, 0x07, 0x7a, 0x00, 0xcc, 0x21, 0x1c, 0xd8, 0x61, 0x1e, 0xca,
0x01, 0xd8, 0x60, 0x10, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x00, 0x12, 0x50, 0x6d, 0x30, 0x8a, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x09, 0xa0, 0x36, 0x10, 0xc6, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x80,
0xb4, 0x81, 0x38, 0x20, 0xe0, 0x0c, 0x00, 0x00, 0x49, 0x18, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x13, 0x86, 0x40, 0x18, 0x26, 0x08, 0xc1, 0x30, 0x21, 0x18, 0x26, 0x04, 0xc4, 0x84, 0xa0, 0x98,
0x10, 0x18, 0x13, 0x82, 0x03, 0x00, 0x00, 0x00, 0x89, 0x20, 0x00, 0x00, 0x69, 0x00, 0x00, 0x00, 0x32, 0x22, 0x88, 0x09, 0x20, 0x64, 0x85, 0x04, 0x13, 0x23, 0xa4, 0x84, 0x04, 0x13, 0x23, 0xe3,
0x84, 0xa1, 0x90, 0x14, 0x12, 0x4c, 0x8c, 0x8c, 0x0b, 0x84, 0xc4, 0x4c, 0x10, 0xbc, 0xc1, 0x1c, 0x01, 0x18, 0x9c, 0x19, 0x48, 0x53, 0x44, 0x09, 0x93, 0xbf, 0x02, 0xd8, 0x14, 0x01, 0x02, 0xd2,
0x18, 0x9a, 0x20, 0x10, 0x0b, 0x11, 0x01, 0x13, 0xe2, 0x34, 0xec, 0x14, 0x51, 0xc2, 0x44, 0x45, 0x04, 0x0a, 0x00, 0x0a, 0x66, 0x00, 0x66, 0xfa, 0xc6, 0x81, 0x1d, 0xc2, 0x61, 0x1e, 0xe6, 0xc1,
0x0d, 0x64, 0xe1, 0x16, 0x66, 0x81, 0x1e, 0xe4, 0xa1, 0x1e, 0xc6, 0x81, 0x1e, 0xea, 0x41, 0x1e, 0xca, 0x81, 0x1c, 0x44, 0xa1, 0x1e, 0xcc, 0xc1, 0x1c, 0xca, 0x41, 0x1e, 0xf8, 0xc0, 0x1c, 0xd8,
0xe1, 0x1d, 0xc2, 0x81, 0x1e, 0xfc, 0x00, 0x05, 0x03, 0x11, 0x33, 0x85, 0xc1, 0x38, 0xb0, 0x43, 0x38, 0xcc, 0xc3, 0x3c, 0xb8, 0x01, 0x2d, 0x94, 0x03, 0x3e, 0xd0, 0x43, 0x3d, 0xc8, 0x43, 0x39,
0xc8, 0x01, 0x29, 0xf0, 0x81, 0x39, 0xb0, 0xc3, 0x3b, 0x84, 0x03, 0x3d, 0xf8, 0x81, 0x1e, 0xe8, 0x41, 0x3b, 0xa4, 0x03, 0x3c, 0xcc, 0xc3, 0x2f, 0xd0, 0x43, 0x3e, 0xc0, 0x43, 0x39, 0xa0, 0x00,
0x98, 0xc9, 0x1a, 0x07, 0x76, 0x08, 0x87, 0x79, 0x98, 0x07, 0x37, 0xa0, 0x85, 0x72, 0xc0, 0x07, 0x7a, 0xa8, 0x07, 0x79, 0x28, 0x07, 0x39, 0x20, 0x05, 0x3e, 0x30, 0x07, 0x76, 0x78, 0x87, 0x70,
0xa0, 0x07, 0x3f, 0x40, 0xc2, 0x60, 0xd0, 0x71, 0x93, 0x34, 0x45, 0x94, 0x30, 0xf9, 0x2c, 0xc0, 0x3c, 0x0b, 0x11, 0xb1, 0x13, 0x30, 0x11, 0x28, 0x00, 0x28, 0x19, 0x01, 0xb8, 0x48, 0x9a, 0x22,
0x4a, 0x98, 0xfc, 0x15, 0xc0, 0x52, 0x00, 0x5b, 0x1c, 0x60, 0x40, 0xc1, 0x40, 0xcc, 0x30, 0x82, 0x30, 0x1c, 0x1b, 0x48, 0x53, 0x44, 0x09, 0x93, 0xbf, 0x51, 0xc8, 0x32, 0x89, 0x4d, 0x1b, 0x21,
0x40, 0x63, 0x2c, 0x84, 0xd8, 0x4c, 0x44, 0x24, 0x11, 0xc2, 0x84, 0x38, 0x8d, 0x36, 0x4d, 0x11, 0x12, 0x50, 0x13, 0x21, 0xa1, 0xc0, 0xa1, 0xa7, 0x0c, 0x4b, 0x03, 0x51, 0x54, 0x84, 0xa5, 0xa1,
0xa9, 0x04, 0x0b, 0x55, 0x37, 0x0d, 0x97, 0x3f, 0x61, 0x0f, 0x21, 0xf9, 0x2b, 0x21, 0xad, 0xc4, 0xe4, 0x17, 0xb7, 0x8d, 0x8a, 0x61, 0x18, 0x06, 0x60, 0x8e, 0x00, 0x21, 0xec, 0x9e, 0xe1, 0xf2,
0x27, 0xec, 0x21, 0x24, 0x3f, 0x04, 0x9a, 0x61, 0x21, 0x50, 0x90, 0x15, 0xe6, 0x02, 0x34, 0x6d, 0x18, 0x86, 0x01, 0x00, 0x80, 0x81, 0xb6, 0x32, 0x00, 0x00, 0x46, 0x5d, 0x89, 0x16, 0x40, 0x03,
0x00, 0x00, 0x00, 0x86, 0x61, 0x18, 0x86, 0x61, 0x18, 0x1a, 0xfa, 0xca, 0xb2, 0x00, 0x1a, 0x00, 0x0c, 0xc3, 0x30, 0x60, 0x00, 0x85, 0x65, 0xd0, 0x80, 0x83, 0xc6, 0x32, 0x68, 0x40, 0x42, 0x65,
0x19, 0x34, 0x20, 0xa0, 0xb3, 0x0c, 0x1a, 0x40, 0x50, 0x3a, 0x10, 0x30, 0x47, 0x10, 0xcc, 0x11, 0x80, 0x02, 0x0d, 0x00, 0x13, 0x14, 0x72, 0xc0, 0x87, 0x74, 0x60, 0x87, 0x36, 0x68, 0x87, 0x79,
0x68, 0x03, 0x72, 0xc0, 0x87, 0x0d, 0xaf, 0x50, 0x0e, 0x6d, 0xd0, 0x0e, 0x7a, 0x50, 0x0e, 0x6d, 0x00, 0x0f, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x71, 0xa0,
0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x78, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x71, 0x60, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, 0xe9, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73,
0x20, 0x07, 0x6d, 0x90, 0x0e, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xe6, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x60, 0x0e, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07,
0x72, 0xd0, 0x06, 0xe6, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, 0xe0, 0x0e, 0x78, 0xa0, 0x07, 0x71, 0x60, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x3a, 0x0f,
0x84, 0x90, 0x21, 0x23, 0x45, 0x44, 0x00, 0xc6, 0x00, 0x80, 0x49, 0x03, 0x00, 0xe6, 0x0d, 0x00, 0x98, 0x39, 0x00, 0x60, 0xe6, 0x00, 0x80, 0x99, 0x03, 0x00, 0x1e, 0xf2, 0x44, 0x00, 0x00, 0x04,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0xe4, 0x89, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0xc8, 0x33, 0x01, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0xc0, 0x90, 0xa7, 0x02, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x21, 0xcf, 0x06, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43, 0x9e, 0x0e, 0x08,
0x80, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86, 0x3c, 0x1f, 0x10, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x79, 0xc2, 0x00, 0x08, 0x00, 0x03, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x86, 0x3c, 0x63, 0x00, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43, 0x9e, 0x32, 0x00, 0x02, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
0x21, 0xcf, 0x19, 0x00, 0x01, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x90, 0x27, 0x0d, 0x80, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x0b, 0x04, 0x00, 0x00,
0x0d, 0x00, 0x00, 0x00, 0x32, 0x1e, 0x98, 0x18, 0x19, 0x11, 0x4c, 0x90, 0x8c, 0x09, 0x26, 0x47, 0xc6, 0x04, 0x43, 0x02, 0x4a, 0xa0, 0x0c, 0x8a, 0x61, 0x04, 0xa0, 0x40, 0x0a, 0xa1, 0x08, 0x4a,
0xa2, 0x30, 0x0a, 0xa2, 0x28, 0xca, 0xa1, 0x14, 0xca, 0x82, 0xd8, 0x11, 0x00, 0x6a, 0x0b, 0x14, 0x10, 0x61, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x79, 0x18, 0x00, 0x00, 0xca, 0x00, 0x00, 0x00,
0x1a, 0x03, 0x4c, 0x90, 0x46, 0x02, 0x13, 0x44, 0x35, 0x18, 0x63, 0x0b, 0x73, 0x3b, 0x03, 0xb1, 0x2b, 0x93, 0x9b, 0x4b, 0x7b, 0x73, 0x03, 0x99, 0x71, 0xb9, 0x01, 0x41, 0xa1, 0x0b, 0x3b, 0x9b,
0x7b, 0x91, 0x2a, 0x62, 0x2a, 0x0a, 0x9a, 0x2a, 0xfa, 0x9a, 0xb9, 0x81, 0x79, 0x31, 0x4b, 0x73, 0x0b, 0x63, 0x4b, 0xd9, 0x10, 0x04, 0x13, 0x04, 0x40, 0x9a, 0x20, 0x00, 0xd3, 0x06, 0x61, 0x20,
0x26, 0x08, 0x00, 0xb5, 0x41, 0x18, 0x0c, 0x0e, 0x6c, 0x69, 0x62, 0x1b, 0x06, 0xc4, 0x20, 0x26, 0x08, 0x40, 0x35, 0x41, 0x10, 0x00, 0x0a, 0x41, 0x53, 0x13, 0x04, 0xc0, 0x9a, 0x20, 0x00, 0xd7,
0x06, 0x41, 0x71, 0x36, 0x24, 0xca, 0xc2, 0x28, 0xca, 0xd0, 0x28, 0xcf, 0x04, 0x01, 0x11, 0x38, 0x50, 0x95, 0xe1, 0x4d, 0x10, 0x00, 0x6c, 0x82, 0x00, 0x64, 0x1b, 0x04, 0x85, 0xda, 0x90, 0x0c,
0x91, 0xa4, 0x0c, 0xc3, 0xa4, 0x54, 0x1b, 0x04, 0xc8, 0x9a, 0x20, 0x14, 0x01, 0x07, 0xa1, 0x3a, 0xb3, 0x09, 0x02, 0xa0, 0x4d, 0x10, 0xd8, 0x00, 0x0c, 0x36, 0x08, 0x83, 0xb3, 0x61, 0x51, 0xb0,
0x4c, 0x51, 0x06, 0x6d, 0xdb, 0x36, 0x6e, 0x43, 0xd0, 0x4d, 0x10, 0x94, 0x81, 0xcc, 0x10, 0x5b, 0x58, 0x1b, 0xdc, 0x54, 0x58, 0x1b, 0x1c, 0x5b, 0x99, 0xdc, 0x06, 0x44, 0xf9, 0xc0, 0x40, 0x51,
0x06, 0x05, 0x98, 0x20, 0x28, 0x04, 0x97, 0x2b, 0xb9, 0x30, 0xb8, 0xa9, 0xb0, 0x36, 0x38, 0xb6, 0x32, 0xb9, 0x0d, 0xc8, 0x20, 0x06, 0x63, 0xa0, 0x0c, 0x83, 0x02, 0x4c, 0x10, 0x94, 0x82, 0xd0,
0x10, 0x5b, 0x58, 0x1b, 0xdc, 0x95, 0x5c, 0x18, 0xdc, 0x54, 0x58, 0x1b, 0x1c, 0x5b, 0x99, 0xdc, 0x06, 0x64, 0x2a, 0x03, 0x33, 0x50, 0xa6, 0x41, 0x01, 0x36, 0x0c, 0x61, 0x40, 0x06, 0x67, 0xb0,
0x81, 0xb8, 0x3c, 0x00, 0x0d, 0x26, 0x08, 0x92, 0xb1, 0x01, 0xd8, 0x30, 0x0c, 0x6b, 0xb0, 0x06, 0x1b, 0x86, 0x69, 0x0d, 0xd6, 0x60, 0xc3, 0xa0, 0xac, 0xc1, 0x1a, 0x6c, 0x18, 0xd8, 0xa0, 0x0d,
0xdc, 0x60, 0x82, 0x20, 0x1d, 0x13, 0x04, 0x0a, 0xd9, 0x20, 0xb0, 0x41, 0x1b, 0x4c, 0x10, 0xac, 0x64, 0x43, 0xc0, 0x06, 0x1b, 0x92, 0x41, 0x0d, 0xde, 0x00, 0x0e, 0xde, 0x20, 0x0e, 0xe4, 0x60,
0x0e, 0xe8, 0x80, 0xc0, 0x04, 0xa1, 0x0d, 0xc2, 0x60, 0x83, 0xa0, 0xdc, 0xc1, 0x86, 0x02, 0xb0, 0x03, 0x20, 0x0d, 0xf0, 0x80, 0xa9, 0x10, 0xf0, 0x23, 0x15, 0x96, 0x37, 0xc4, 0xf6, 0x36, 0x57,
0x36, 0x47, 0x17, 0x03, 0x04, 0x94, 0x15, 0x84, 0x55, 0x25, 0x15, 0x96, 0x07, 0x15, 0x96, 0xc7, 0xf6, 0x16, 0x46, 0x06, 0x04, 0x54, 0x25, 0x54, 0x97, 0xc6, 0x46, 0x97, 0xe4, 0x46, 0x25, 0x97,
0x16, 0xe6, 0x76, 0xc6, 0x56, 0x96, 0xe4, 0x46, 0x57, 0x26, 0x37, 0x57, 0x36, 0x46, 0x97, 0xf6, 0xe6, 0x16, 0x44, 0x47, 0x27, 0x97, 0x26, 0x56, 0x47, 0x57, 0x36, 0x07, 0x04, 0x04, 0xa4, 0x35,
0x41, 0x00, 0xb6, 0x09, 0x02, 0xc0, 0x4d, 0x10, 0x80, 0x6e, 0x82, 0x00, 0x78, 0x1b, 0x02, 0x65, 0x03, 0xb2, 0x07, 0x7c, 0x60, 0x38, 0x7d, 0xb0, 0x07, 0x7e, 0xf0, 0x07, 0x1b, 0x0a, 0x35, 0xd0,
0x03, 0x00, 0x00, 0x05, 0xa6, 0x42, 0xc0, 0x8f, 0x54, 0x58, 0xde, 0x10, 0xdb, 0xdb, 0x5c, 0xd9, 0x1c, 0x9d, 0x0c, 0x10, 0x50, 0x56, 0x10, 0x56, 0x95, 0x54, 0x58, 0x1e, 0x54, 0x58, 0x1e, 0xdb,
0x5b, 0x18, 0x19, 0x10, 0x50, 0x95, 0x50, 0x5d, 0x1a, 0x1b, 0x5d, 0x92, 0x1b, 0x95, 0x5c, 0x5a, 0x98, 0xdb, 0x19, 0x5b, 0x59, 0x92, 0x1b, 0x5d, 0x99, 0xdc, 0x5c, 0xd9, 0x18, 0x5d, 0xda, 0x9b,
0x5b, 0x10, 0x1d, 0x9d, 0x5c, 0x9a, 0x58, 0x1d, 0x5d, 0xd9, 0x1c, 0x10, 0x10, 0x90, 0xd6, 0x86, 0x02, 0x0e, 0x44, 0x01, 0x00, 0x40, 0x81, 0x4f, 0xc0, 0x8f, 0x54, 0x58, 0xde, 0x51, 0x99, 0x1b,
0x10, 0x50, 0x56, 0x10, 0x16, 0x96, 0xd6, 0x06, 0x62, 0x0f, 0xfa, 0xc0, 0x0f, 0xfe, 0x60, 0x43, 0x31, 0x07, 0xa4, 0x00, 0x00, 0xa5, 0xc0, 0x2e, 0xe0, 0x47, 0x2a, 0x2c, 0xaf, 0x29, 0x6d, 0x6e,
0x0e, 0x08, 0x28, 0x2b, 0x08, 0xab, 0x4a, 0x2a, 0x2c, 0x0f, 0x2a, 0x2c, 0x8f, 0xed, 0x2d, 0x8c, 0x0c, 0x08, 0x08, 0x48, 0x6b, 0x82, 0x00, 0x7c, 0x1b, 0x8c, 0x3d, 0x40, 0x05, 0xc3, 0xf1, 0x83,
0x3f, 0xd8, 0x50, 0xc4, 0xc1, 0x29, 0x00, 0x40, 0x2a, 0xb0, 0x30, 0x63, 0x7b, 0x0b, 0xa3, 0xe3, 0xf3, 0xd6, 0xe6, 0x96, 0x06, 0xf7, 0x46, 0x57, 0xe6, 0x46, 0x07, 0x32, 0x86, 0x16, 0x26, 0xc7,
0x68, 0x2a, 0xad, 0x0d, 0x8e, 0xad, 0x0c, 0x64, 0xe8, 0x65, 0x68, 0x65, 0x05, 0x84, 0x4a, 0x28, 0x28, 0x68, 0x43, 0xd0, 0x0a, 0x13, 0x84, 0x36, 0x10, 0x83, 0x0d, 0x03, 0x2b, 0xb8, 0xc2, 0x2b,
0x6c, 0x18, 0x56, 0x01, 0x16, 0x5e, 0x61, 0xc3, 0x10, 0x0b, 0xb1, 0xf0, 0x0a, 0x55, 0xd8, 0xd8, 0xec, 0xda, 0x5c, 0xd2, 0xc8, 0xca, 0xdc, 0xe8, 0xa6, 0x04, 0x41, 0x15, 0x32, 0x3c, 0x17, 0xbb,
0x32, 0xb9, 0xb9, 0xb4, 0x37, 0xb7, 0x29, 0x01, 0xd1, 0x84, 0x0c, 0xcf, 0xc5, 0x2e, 0x8c, 0xcd, 0xae, 0x4c, 0x6e, 0x4a, 0x60, 0xd4, 0x21, 0xc3, 0x73, 0x99, 0x43, 0x0b, 0x23, 0x2b, 0x93, 0x6b,
0x7a, 0x23, 0x2b, 0x63, 0x9b, 0x12, 0x20, 0x65, 0xc8, 0xf0, 0x5c, 0xe4, 0xca, 0xe6, 0xde, 0xea, 0xe4, 0xc6, 0xca, 0xe6, 0xa6, 0x04, 0x68, 0x50, 0x89, 0x0c, 0xcf, 0x85, 0x2e, 0x0f, 0xae, 0x2c,
0xc8, 0xcd, 0xed, 0x8d, 0x2e, 0x8c, 0x2e, 0xed, 0xcd, 0x6d, 0x6e, 0x4a, 0x40, 0x07, 0x75, 0xc8, 0xf0, 0x5c, 0xca, 0xdc, 0xe8, 0xe4, 0xf2, 0xa0, 0xde, 0xd2, 0xdc, 0xe8, 0xe6, 0xa6, 0x14, 0x78,
0x00, 0x0a, 0xa2, 0x50, 0x0a, 0xa9, 0x00, 0x00, 0x79, 0x18, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x33, 0x08, 0x80, 0x1c, 0xc4, 0xe1, 0x1c, 0x66, 0x14, 0x01, 0x3d, 0x88, 0x43, 0x38, 0x84, 0xc3,
0x8c, 0x42, 0x80, 0x07, 0x79, 0x78, 0x07, 0x73, 0x98, 0x71, 0x0c, 0xe6, 0x00, 0x0f, 0xed, 0x10, 0x0e, 0xf4, 0x80, 0x0e, 0x33, 0x0c, 0x42, 0x1e, 0xc2, 0xc1, 0x1d, 0xce, 0xa1, 0x1c, 0x66, 0x30,
0x05, 0x3d, 0x88, 0x43, 0x38, 0x84, 0x83, 0x1b, 0xcc, 0x03, 0x3d, 0xc8, 0x43, 0x3d, 0x8c, 0x03, 0x3d, 0xcc, 0x78, 0x8c, 0x74, 0x70, 0x07, 0x7b, 0x08, 0x07, 0x79, 0x48, 0x87, 0x70, 0x70, 0x07,
0x7a, 0x70, 0x03, 0x76, 0x78, 0x87, 0x70, 0x20, 0x87, 0x19, 0xcc, 0x11, 0x0e, 0xec, 0x90, 0x0e, 0xe1, 0x30, 0x0f, 0x6e, 0x30, 0x0f, 0xe3, 0xf0, 0x0e, 0xf0, 0x50, 0x0e, 0x33, 0x10, 0xc4, 0x1d,
0xde, 0x21, 0x1c, 0xd8, 0x21, 0x1d, 0xc2, 0x61, 0x1e, 0x66, 0x30, 0x89, 0x3b, 0xbc, 0x83, 0x3b, 0xd0, 0x43, 0x39, 0xb4, 0x03, 0x3c, 0xbc, 0x83, 0x3c, 0x84, 0x03, 0x3b, 0xcc, 0xf0, 0x14, 0x76,
0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x68, 0x87, 0x72, 0x68, 0x07, 0x37, 0x80, 0x87, 0x70, 0x90, 0x87, 0x70, 0x60, 0x07, 0x76, 0x28, 0x07, 0x76, 0xf8, 0x05, 0x76, 0x78, 0x87, 0x77, 0x80, 0x87,
0x5f, 0x08, 0x87, 0x71, 0x18, 0x87, 0x72, 0x98, 0x87, 0x79, 0x98, 0x81, 0x2c, 0xee, 0xf0, 0x0e, 0xee, 0xe0, 0x0e, 0xf5, 0xc0, 0x0e, 0xec, 0x30, 0x03, 0x62, 0xc8, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c,
0xcc, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xdc, 0x61, 0x1c, 0xca, 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca, 0x61, 0x06, 0xd6, 0x90, 0x43, 0x39, 0xc8, 0x43, 0x39, 0x98, 0x43, 0x39, 0xc8, 0x43, 0x39, 0xb8,
0xc3, 0x38, 0x94, 0x43, 0x38, 0x88, 0x03, 0x3b, 0x94, 0xc3, 0x2f, 0xbc, 0x83, 0x3c, 0xfc, 0x82, 0x3b, 0xd4, 0x03, 0x3b, 0xb0, 0xc3, 0x8c, 0xc8, 0x21, 0x07, 0x7c, 0x70, 0x03, 0x72, 0x10, 0x87,
0x73, 0x70, 0x03, 0x7b, 0x08, 0x07, 0x79, 0x60, 0x87, 0x70, 0xc8, 0x87, 0x77, 0xa8, 0x07, 0x7a, 0x00, 0x00, 0x00, 0x00, 0x71, 0x20, 0x00, 0x00, 0xa1, 0x00, 0x00, 0x00, 0x05, 0xa0, 0x06, 0x81,
0x5f, 0x70, 0x0a, 0x04, 0xce, 0xaa, 0xd2, 0x70, 0x9e, 0x2e, 0x0f, 0x8f, 0xd3, 0xee, 0x73, 0x70, 0x3c, 0x2e, 0xb3, 0xcb, 0xf2, 0x30, 0x3d, 0xfd, 0x76, 0x4f, 0xe9, 0xf2, 0xfa, 0x98, 0x5e, 0x97,
0x97, 0x81, 0xc0, 0x60, 0x05, 0x88, 0x41, 0xe0, 0x27, 0xac, 0x9b, 0x81, 0xc0, 0x99, 0xf5, 0x47, 0x92, 0x5e, 0xa7, 0x74, 0x79, 0x7d, 0x4c, 0xaf, 0xcb, 0xcb, 0x64, 0x61, 0xdd, 0x6c, 0x2e, 0xcb,
0x81, 0x4d, 0x20, 0x30, 0x58, 0x03, 0x61, 0x10, 0xf8, 0x0d, 0xd9, 0xe1, 0x36, 0x7c, 0x1a, 0x6e, 0xc3, 0xd9, 0x65, 0x39, 0x10, 0x38, 0xab, 0x4e, 0xc3, 0x6d, 0x38, 0xbb, 0x2c, 0x9f, 0xd2, 0xc3,
0xf4, 0x32, 0x10, 0x18, 0xac, 0x82, 0x32, 0x08, 0xfc, 0x86, 0xec, 0x70, 0x1b, 0x7e, 0x95, 0x87, 0xe1, 0xd3, 0x70, 0x1b, 0xce, 0x2e, 0xcb, 0x81, 0xc0, 0x59, 0x75, 0x1a, 0x6e, 0xc3, 0xd9, 0x65,
0xf9, 0x94, 0x1e, 0xa6, 0x97, 0x81, 0xc0, 0x60, 0x19, 0xa4, 0x42, 0xe0, 0x27, 0x0d, 0xe7, 0x87, 0xec, 0xf7, 0xbc, 0x3c, 0xa7, 0xc7, 0x80, 0xc0, 0x6c, 0x10, 0x5b, 0x95, 0x86, 0xf3, 0xd0, 0x70,
0x9e, 0xfd, 0x0e, 0x93, 0x81, 0xc0, 0xaa, 0xb0, 0x9e, 0x66, 0xd3, 0x93, 0x6e, 0xaa, 0x3c, 0x1d, 0x76, 0x9f, 0xd9, 0xe5, 0xa4, 0x9b, 0x5e, 0x96, 0xcf, 0xcb, 0x63, 0x7a, 0xfa, 0xed, 0x0e, 0xd2,
0xe9, 0xf2, 0xb4, 0xb8, 0x4e, 0x2f, 0xcf, 0x81, 0x40, 0xa0, 0xb6, 0x0e, 0x52, 0x21, 0xf0, 0x93, 0x86, 0xf3, 0x43, 0xf6, 0x7b, 0x5e, 0x9e, 0xd3, 0x65, 0x40, 0x60, 0x36, 0x88, 0xad, 0x4a, 0xc3,
0x79, 0x68, 0x38, 0xcf, 0x7e, 0x87, 0xc9, 0x40, 0x60, 0x55, 0x58, 0x4f, 0xb3, 0xe9, 0x49, 0x37, 0x55, 0x9e, 0x0e, 0xbb, 0xcf, 0xec, 0x72, 0xd2, 0x4d, 0x2f, 0xcb, 0xe7, 0xe5, 0x31, 0x3d, 0xfd,
0x76, 0x07, 0xe9, 0x74, 0x79, 0x5a, 0x5c, 0xa7, 0x97, 0xe7, 0x40, 0x20, 0x50, 0x5b, 0x09, 0x4f, 0xe0, 0x27, 0x0d, 0xe7, 0x8f, 0x65, 0x37, 0x10, 0x98, 0x0d, 0x62, 0xb1, 0xda, 0x42, 0xe8, 0x02,
0x3f, 0x69, 0x38, 0xdf, 0x4c, 0xcf, 0xe7, 0x40, 0x60, 0x36, 0x88, 0xad, 0x4a, 0xc3, 0x79, 0x68, 0x38, 0xcf, 0x7e, 0x87, 0xc9, 0x40, 0x20, 0x50, 0x5b, 0x02, 0x59, 0xe0, 0x47, 0x2d, 0xe3, 0x81,
0xc0, 0x99, 0xf5, 0x47, 0xa2, 0x96, 0xf1, 0xf4, 0xba, 0xbc, 0x2c, 0x23, 0x02, 0x9b, 0x40, 0x60, 0xb0, 0x08, 0xc0, 0x20, 0xf0, 0xbb, 0xca, 0xc3, 0xf0, 0x69, 0xb8, 0x0d, 0x67, 0x97, 0xe5, 0x40,
0xe0, 0xac, 0x3a, 0x0d, 0xb7, 0xe1, 0xec, 0xb2, 0x7c, 0x4a, 0x0f, 0xd3, 0xcb, 0x40, 0x60, 0xb0, 0x22, 0xf0, 0x80, 0x8c, 0x77, 0xbd, 0xe1, 0xae, 0xb1, 0xbc, 0x1c, 0xa6, 0x97, 0x91, 0x61, 0x37,
0x99, 0x5d, 0x36, 0xbe, 0xe5, 0xcc, 0xb4, 0xd8, 0x35, 0x66, 0x87, 0xe7, 0x73, 0x97, 0xf4, 0x3a, 0xa5, 0xcb, 0xeb, 0x63, 0x7a, 0x5d, 0x5e, 0x26, 0x0b, 0xeb, 0x66, 0x73, 0x59, 0xce, 0x33, 0xb3,
0xdf, 0x61, 0xba, 0xaf, 0x1c, 0xde, 0x80, 0x8c, 0x77, 0xbd, 0xe1, 0xae, 0xb1, 0xbc, 0x1c, 0xa6, 0x97, 0x91, 0x61, 0x37, 0x99, 0x5d, 0x36, 0xbe, 0xe5, 0xcc, 0xb4, 0xd8, 0x35, 0x66, 0x87, 0xe7,
0x73, 0x17, 0xb5, 0x8c, 0xa7, 0xd7, 0xe5, 0x65, 0x19, 0x91, 0x67, 0x66, 0xbf, 0xc3, 0x74, 0x9f, 0x41, 0xfc, 0xc1, 0x70, 0xf9, 0xce, 0xe3, 0x0b, 0x11, 0x01, 0x4c, 0x44, 0x08, 0x34, 0xc3, 0x42,
0x7c, 0x4e, 0x54, 0x22, 0x81, 0x2f, 0x4d, 0x11, 0x25, 0x4c, 0xfe, 0x0a, 0x60, 0x53, 0x04, 0x08, 0x48, 0x63, 0x68, 0x82, 0x40, 0x2c, 0x44, 0x04, 0x4c, 0x88, 0xd3, 0xb0, 0x53, 0x44, 0x09, 0x13,
0x15, 0x11, 0xf6, 0xc0, 0x06, 0xc3, 0xe5, 0x3b, 0x8f, 0x2f, 0x44, 0x04, 0x30, 0x11, 0x21, 0xd0, 0x0c, 0x0b, 0xf1, 0x39, 0x51, 0x89, 0x04, 0xbe, 0x34, 0x45, 0x94, 0x30, 0xf9, 0x2c, 0xc0, 0x3c,
0x0b, 0x11, 0xb1, 0x13, 0x30, 0x11, 0xb6, 0xb0, 0x0d, 0x97, 0xef, 0x3c, 0xfe, 0x80, 0x48, 0x0f, 0x30, 0x09, 0xc7, 0x0a, 0x60, 0x92, 0xd8, 0x0c, 0xc4, 0xe5, 0x23, 0xb7, 0x6d, 0x0d, 0xd8, 0x70,
0xf9, 0xce, 0xe3, 0x47, 0x80, 0xb5, 0x51, 0x45, 0x41, 0x44, 0xec, 0xe4, 0x44, 0x84, 0x5f, 0xdc, 0xb6, 0x29, 0x54, 0xc3, 0xe5, 0x3b, 0x8f, 0x2f, 0x01, 0xcc, 0xb3, 0x10, 0x25, 0x51, 0x11, 0x8b,
0x5f, 0xdc, 0xb6, 0x31, 0x80, 0xc1, 0x70, 0xf9, 0xce, 0xe3, 0x4f, 0x11, 0x20, 0x10, 0x2b, 0x80, 0xf9, 0xd2, 0x14, 0x51, 0xc2, 0xe4, 0xaf, 0x00, 0x96, 0x02, 0xd8, 0xe2, 0x00, 0x03, 0x00, 0x00,
0x61, 0x20, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x13, 0x04, 0x41, 0x2c, 0x10, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x14, 0xb0, 0x40, 0xf1, 0xcd, 0x00, 0xd0, 0x30, 0x46, 0x00, 0x82,
0x20, 0xa8, 0x7f, 0x33, 0x00, 0x23, 0x00, 0x00, 0x64, 0x06, 0xc9, 0xa0, 0x34, 0x48, 0x06, 0xad, 0xc1, 0x31, 0x46, 0x0c, 0x0c, 0x00, 0x04, 0xc1, 0x60, 0x0c, 0xc0, 0x20, 0x09, 0x46, 0x0c, 0x0c,
0x00, 0x04, 0xc1, 0xa0, 0x0c, 0xc0, 0x40, 0x19, 0x46, 0x0c, 0x1e, 0x00, 0x04, 0xc1, 0x60, 0x33, 0x03, 0x45, 0x08, 0x10, 0xe4, 0x38, 0xb6, 0x2d, 0x31, 0x46, 0x13, 0x02, 0x60, 0xc4, 0xc0, 0x00,
0x40, 0x10, 0x0c, 0xca, 0x60, 0x0c, 0x9a, 0x63, 0xc4, 0xe0, 0x01, 0x40, 0x10, 0x0c, 0xb6, 0x34, 0x68, 0x8a, 0x60, 0x59, 0x14, 0xc5, 0xf3, 0x98, 0x64, 0x34, 0x21, 0x00, 0x2c, 0x20, 0xe0, 0xb3,
0x99, 0x61, 0x0a, 0x83, 0x30, 0x18, 0x36, 0x20, 0x02, 0x61, 0x00, 0x30, 0x1c, 0x08, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x46, 0x62, 0x00, 0xd3, 0x14, 0x21, 0x81, 0x8d, 0x1c, 0x0f, 0x80, 0x2d,
0x0e, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x61, 0x20, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x13, 0x04, 0x41, 0x2c, 0x10, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x14, 0xb0, 0x40,
0xf1, 0xcd, 0x00, 0xd0, 0x30, 0x46, 0x00, 0x82, 0x20, 0xa8, 0x7f, 0x33, 0x00, 0x23, 0x00, 0x00, 0x64, 0x06, 0xc9, 0x20, 0x34, 0x48, 0x06, 0xad, 0xc1, 0x31, 0x46, 0x0c, 0x0c, 0x00, 0x04, 0xc1,
0x60, 0x0c, 0xc0, 0x20, 0x09, 0x46, 0x0c, 0x0c, 0x00, 0x04, 0xc1, 0xa0, 0x0c, 0xc0, 0x40, 0x19, 0x46, 0x0c, 0x1e, 0x00, 0x04, 0xc1, 0x60, 0x33, 0x03, 0x45, 0x08, 0x10, 0xe4, 0x38, 0xb6, 0x2d,
0x31, 0x46, 0x13, 0x02, 0x60, 0xc4, 0xc0, 0x00, 0x40, 0x10, 0x0c, 0xca, 0x60, 0x0c, 0x9a, 0x63, 0xc4, 0xe0, 0x01, 0x40, 0x10, 0x0c, 0xb6, 0x34, 0x68, 0x8a, 0x60, 0x59, 0x14, 0xc5, 0xf3, 0x98,
0x64, 0x34, 0x21, 0x00, 0x2c, 0x20, 0xe0, 0xb3, 0x99, 0x61, 0x0a, 0x83, 0x30, 0x18, 0x36, 0x20, 0x02, 0x61, 0x00, 0x30, 0x1c, 0x08, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x46, 0x62, 0x00, 0xd3,
0x14, 0x21, 0x81, 0x8d, 0x1c, 0x0f, 0x80, 0x2d, 0x0e, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x61, 0x20, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x13, 0x04, 0x41, 0x2c, 0x10, 0x00, 0x00, 0x00,
0x03, 0x00, 0x00, 0x00, 0x34, 0x8c, 0x11, 0x80, 0x20, 0x08, 0xe2, 0xbf, 0x00, 0x00, 0x00, 0x00, 0x9b, 0x19, 0x04, 0x08, 0x1a, 0x36, 0x20, 0x02, 0x61, 0x00, 0x30, 0x1c, 0x08, 0x00, 0x00, 0x00,
0x02, 0x00, 0x00, 0x00, 0x36, 0x72, 0x3c, 0x00, 0xb6, 0x38, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x61, 0x20, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x13, 0x04, 0x41, 0x2c, 0x10, 0x00, 0x00, 0x00,
0x0b, 0x00, 0x00, 0x00, 0x04, 0x94, 0xa8, 0x40, 0x01, 0x0b, 0x94, 0xae, 0x40, 0x61, 0x0a, 0x10, 0x36, 0x02, 0x50, 0x02, 0x34, 0xcc, 0x00, 0x8c, 0x11, 0x80, 0x20, 0x08, 0xe2, 0xdf, 0x18, 0x01,
0x08, 0x82, 0x20, 0xfe, 0x0b, 0x63, 0x04, 0x20, 0x08, 0x82, 0x32, 0x18, 0x8c, 0x00, 0x00, 0x00, 0xe4, 0x06, 0xc1, 0x20, 0x37, 0x20, 0xc6, 0x4c, 0x04, 0x03, 0x48, 0xa3, 0xb0, 0x99, 0x21, 0xe0,
0xb8, 0x61, 0x03, 0x22, 0x28, 0x06, 0x60, 0xc4, 0xc0, 0x00, 0x40, 0x10, 0x0c, 0xba, 0x33, 0x78, 0x96, 0x11, 0x03, 0x03, 0x00, 0x41, 0x30, 0xe8, 0xd0, 0x00, 0x5a, 0x4e, 0x18, 0xea, 0x84, 0xa1,
0x4c, 0x50, 0xe4, 0x63, 0xc2, 0x22, 0x9f, 0x11, 0x03, 0x03, 0x00, 0x41, 0x30, 0x38, 0x03, 0x34, 0xa0, 0x94, 0x11, 0x03, 0xea, 0x00, 0x41, 0x30, 0xf8, 0xda, 0x80, 0x0a, 0xc8, 0xe0, 0x0c, 0xc8,
0xe0, 0x0c, 0xc8, 0x60, 0x10, 0x1e, 0x86, 0x61, 0x9c, 0x26, 0x21, 0x64, 0x18, 0x75, 0xa0, 0xc1, 0x55, 0x90, 0xc0, 0x88, 0x81, 0x01, 0x80, 0x20, 0x18, 0xa4, 0xc1, 0x1a, 0x60, 0xcd, 0x88, 0x81,
0x03, 0x80, 0x20, 0x18, 0x84, 0x01, 0x1c, 0x5c, 0x81, 0x80, 0x06, 0x04, 0x45, 0x51, 0x95, 0x19, 0x60, 0x40, 0x0c, 0x00, 0x03, 0x00, 0x00, 0x00, 0x5b, 0x06, 0x22, 0x88, 0x85, 0x2d, 0x43, 0x13,
0xc4, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
D3D12_SHADER_BYTECODE code;
code.pShaderBytecode = rt_lib_dxil;
code.BytecodeLength = sizeof(rt_lib_dxil);
return code;
}
static D3D12_SHADER_BYTECODE get_default_rt_lib(void)
{
/* Compile with -Tlib_6_3 in DXC. */
static const BYTE rt_lib_dxil[] =
{
#if 0
RaytracingAccelerationStructure AS : register(t0);
StructuredBuffer<float2> RayPositions : register(t1);
RWStructuredBuffer<float2> Buf : register(u0);
struct RayPayload
{
float2 color;
};
cbuffer LocalConstants : register(b0, space1)
{
float local_value0;
};
cbuffer LocalConstants2 : register(b1, space1)
{
float local_value1;
};
struct AABBAttribs { float dummy; };
[shader("miss")]
void RayMiss(inout RayPayload payload)
{
payload.color.x += local_value0;
payload.color.y += local_value1;
}
[shader("closesthit")]
void RayClosest(inout RayPayload payload, BuiltInTriangleIntersectionAttributes attribs)
{
payload.color.x += local_value0;
payload.color.y += local_value1;
}
[shader("anyhit")]
void RayAnyTriangle(inout RayPayload payload, BuiltInTriangleIntersectionAttributes attribs)
{
payload.color.x += 1.0;
IgnoreHit();
}
[shader("anyhit")]
void RayAnyAABB(inout RayPayload payload, AABBAttribs attribs)
{
payload.color.y += attribs.dummy;
IgnoreHit();
}
[shader("intersection")]
void RayIntersect()
{
AABBAttribs dummy;
dummy.dummy = 1.0;
float thit = 1.0; // Hardcode an intersection at origin of the AABB.
ReportHit(thit, 0, dummy);
}
cbuffer Flags : register(b0, space0) { uint flags; };
[shader("raygeneration")]
void RayGen()
{
RayPayload payload;
payload.color = float2(0.0, 0.0);
uint index = DispatchRaysIndex().x;
RayDesc ray;
ray.Origin = float3(RayPositions[index], 1.0);
ray.Direction = float3(0.0, 0.0, -1.0);
ray.TMin = 0;
ray.TMax = 10;
TraceRay(AS, flags,
0x01, // mask
0, // HitGroup offset
1, // geometry contribution multiplier
0, // miss shader index
ray, payload);
Buf[index] = payload.color;
}
#endif
0x44, 0x58, 0x42, 0x43, 0x18, 0x37, 0x14, 0x5f, 0xe5, 0xfe, 0x39, 0xa9, 0x76, 0x18, 0x41, 0xc8, 0x09, 0xc1, 0x25, 0x1a, 0x01, 0x00, 0x00, 0x00, 0x8c, 0x17, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
0x30, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0xfc, 0x03, 0x00, 0x00, 0x18, 0x04, 0x00, 0x00, 0x53, 0x46, 0x49, 0x30, 0x08, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x52, 0x44, 0x41, 0x54, 0xb4, 0x03, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0xa4, 0x01, 0x00, 0x00, 0x74, 0x02, 0x00, 0x00, 0x8c, 0x03, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x84, 0x01, 0x00, 0x00, 0x00, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x43, 0x6f, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x73, 0x00, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x43, 0x6f, 0x6e,
0x73, 0x74, 0x61, 0x6e, 0x74, 0x73, 0x32, 0x00, 0x46, 0x6c, 0x61, 0x67, 0x73, 0x00, 0x41, 0x53, 0x00, 0x52, 0x61, 0x79, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x00, 0x42, 0x75,
0x66, 0x00, 0x01, 0x3f, 0x52, 0x61, 0x79, 0x4d, 0x69, 0x73, 0x73, 0x40, 0x40, 0x59, 0x41, 0x58, 0x55, 0x52, 0x61, 0x79, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x40, 0x40, 0x40, 0x5a, 0x00,
0x52, 0x61, 0x79, 0x4d, 0x69, 0x73, 0x73, 0x00, 0x01, 0x3f, 0x52, 0x61, 0x79, 0x43, 0x6c, 0x6f, 0x73, 0x65, 0x73, 0x74, 0x40, 0x40, 0x59, 0x41, 0x58, 0x55, 0x52, 0x61, 0x79, 0x50, 0x61, 0x79,
0x6c, 0x6f, 0x61, 0x64, 0x40, 0x40, 0x55, 0x42, 0x75, 0x69, 0x6c, 0x74, 0x49, 0x6e, 0x54, 0x72, 0x69, 0x61, 0x6e, 0x67, 0x6c, 0x65, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x65, 0x63, 0x74, 0x69,
0x6f, 0x6e, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x40, 0x40, 0x40, 0x5a, 0x00, 0x52, 0x61, 0x79, 0x43, 0x6c, 0x6f, 0x73, 0x65, 0x73, 0x74, 0x00, 0x01, 0x3f, 0x52, 0x61,
0x79, 0x41, 0x6e, 0x79, 0x54, 0x72, 0x69, 0x61, 0x6e, 0x67, 0x6c, 0x65, 0x40, 0x40, 0x59, 0x41, 0x58, 0x55, 0x52, 0x61, 0x79, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x40, 0x40, 0x55, 0x42,
0x75, 0x69, 0x6c, 0x74, 0x49, 0x6e, 0x54, 0x72, 0x69, 0x61, 0x6e, 0x67, 0x6c, 0x65, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62,
0x75, 0x74, 0x65, 0x73, 0x40, 0x40, 0x40, 0x5a, 0x00, 0x52, 0x61, 0x79, 0x41, 0x6e, 0x79, 0x54, 0x72, 0x69, 0x61, 0x6e, 0x67, 0x6c, 0x65, 0x00, 0x01, 0x3f, 0x52, 0x61, 0x79, 0x41, 0x6e, 0x79,
0x41, 0x41, 0x42, 0x42, 0x40, 0x40, 0x59, 0x41, 0x58, 0x55, 0x52, 0x61, 0x79, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x40, 0x40, 0x55, 0x41, 0x41, 0x42, 0x42, 0x41, 0x74, 0x74, 0x72, 0x69,
0x62, 0x73, 0x40, 0x40, 0x40, 0x5a, 0x00, 0x52, 0x61, 0x79, 0x41, 0x6e, 0x79, 0x41, 0x41, 0x42, 0x42, 0x00, 0x01, 0x3f, 0x52, 0x61, 0x79, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x65, 0x63, 0x74,
0x40, 0x40, 0x59, 0x41, 0x58, 0x58, 0x5a, 0x00, 0x52, 0x61, 0x79, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x65, 0x63, 0x74, 0x00, 0x01, 0x3f, 0x52, 0x61, 0x79, 0x47, 0x65, 0x6e, 0x40, 0x40, 0x59,
0x41, 0x58, 0x58, 0x5a, 0x00, 0x52, 0x61, 0x79, 0x47, 0x65, 0x6e, 0x00, 0x03, 0x00, 0x00, 0x00, 0xc8, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
0x0d, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
0x0d, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x0c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
0x10, 0x01, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x0b, 0x00, 0x00, 0x00,
0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x60, 0x00, 0x0b, 0x00, 0x60, 0x00, 0x00, 0x00, 0xa9, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x0a, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00,
0x60, 0x00, 0x0a, 0x00, 0xb4, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x09, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x63, 0x00, 0x09, 0x00, 0x10, 0x01, 0x00, 0x00, 0x3f, 0x01, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0x09, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x63, 0x00, 0x09, 0x00, 0x4a, 0x01, 0x00, 0x00,
0x60, 0x01, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x01, 0x00, 0x00, 0x63, 0x00, 0x08, 0x00, 0x6d, 0x01, 0x00, 0x00, 0x7d, 0x01, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x63, 0x00, 0x07, 0x00, 0x02, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x48, 0x41, 0x53, 0x48,
0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbe, 0xc5, 0xab, 0xda, 0x17, 0x70, 0x07, 0xc6, 0x87, 0x58, 0x79, 0x1e, 0x8e, 0xa6, 0x90, 0x3e, 0x44, 0x58, 0x49, 0x4c, 0x6c, 0x13, 0x00, 0x00,
0x63, 0x00, 0x06, 0x00, 0xdb, 0x04, 0x00, 0x00, 0x44, 0x58, 0x49, 0x4c, 0x03, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x54, 0x13, 0x00, 0x00, 0x42, 0x43, 0xc0, 0xde, 0x21, 0x0c, 0x00, 0x00,
0xd2, 0x04, 0x00, 0x00, 0x0b, 0x82, 0x20, 0x00, 0x02, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x07, 0x81, 0x23, 0x91, 0x41, 0xc8, 0x04, 0x49, 0x06, 0x10, 0x32, 0x39, 0x92, 0x01, 0x84, 0x0c,
0x25, 0x05, 0x08, 0x19, 0x1e, 0x04, 0x8b, 0x62, 0x80, 0x1c, 0x45, 0x02, 0x42, 0x92, 0x0b, 0x42, 0xe4, 0x10, 0x32, 0x14, 0x38, 0x08, 0x18, 0x4b, 0x0a, 0x32, 0x72, 0x88, 0x48, 0x90, 0x14, 0x20,
0x43, 0x46, 0x88, 0xa5, 0x00, 0x19, 0x32, 0x42, 0xe4, 0x48, 0x0e, 0x90, 0x91, 0x23, 0xc4, 0x50, 0x41, 0x51, 0x81, 0x8c, 0xe1, 0x83, 0xe5, 0x8a, 0x04, 0x39, 0x46, 0x06, 0x51, 0x18, 0x00, 0x00,
0xb3, 0x00, 0x00, 0x00, 0x1b, 0x8c, 0x20, 0x00, 0x12, 0x60, 0xd9, 0x00, 0x1e, 0xc2, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x80, 0x44, 0x90, 0x43, 0x3a, 0xcc, 0x43, 0x38, 0x88, 0x03, 0x3b, 0x94, 0x43,
0x1b, 0xd0, 0x43, 0x38, 0xa4, 0x03, 0x3b, 0xb4, 0xc1, 0x38, 0x84, 0x03, 0x3b, 0xb0, 0xc3, 0x3c, 0x00, 0xe6, 0x10, 0x0e, 0xec, 0x30, 0x0f, 0xe5, 0x00, 0x10, 0xec, 0x50, 0x0e, 0xf3, 0x30, 0x0f,
0x6d, 0x00, 0x0f, 0xf2, 0x50, 0x0e, 0xe3, 0x90, 0x0e, 0xf3, 0x50, 0x0e, 0x6d, 0x60, 0x0e, 0xf0, 0xd0, 0x0e, 0xe1, 0x40, 0x0e, 0x80, 0x39, 0x84, 0x03, 0x3b, 0xcc, 0x43, 0x39, 0x00, 0x84, 0x3b,
0xbc, 0x43, 0x1b, 0x98, 0x83, 0x3c, 0x84, 0x43, 0x3b, 0x94, 0x43, 0x1b, 0xc0, 0xc3, 0x3b, 0xa4, 0x83, 0x3b, 0xd0, 0x43, 0x39, 0xc8, 0x43, 0x1b, 0x94, 0x03, 0x3b, 0xa4, 0x43, 0x3b, 0x00, 0xe6,
0x10, 0x0e, 0xec, 0x30, 0x0f, 0xe5, 0x00, 0x10, 0xee, 0xf0, 0x0e, 0x6d, 0x90, 0x0e, 0xee, 0x60, 0x0e, 0xf3, 0xd0, 0x06, 0xe6, 0x00, 0x0f, 0x6d, 0xd0, 0x0e, 0xe1, 0x40, 0x0f, 0xe8, 0x00, 0x98,
0x43, 0x38, 0xb0, 0xc3, 0x3c, 0x94, 0x03, 0x40, 0xb8, 0xc3, 0x3b, 0xb4, 0x81, 0x3b, 0x84, 0x83, 0x3b, 0xcc, 0x43, 0x1b, 0x98, 0x03, 0x3c, 0xb4, 0x41, 0x3b, 0x84, 0x03, 0x3d, 0xa0, 0x03, 0x60,
0x0e, 0xe1, 0xc0, 0x0e, 0xf3, 0x50, 0x0e, 0xc0, 0xe0, 0x0e, 0xef, 0xd0, 0x06, 0xf2, 0x50, 0x0e, 0xe1, 0xc0, 0x0e, 0xe9, 0x70, 0x0e, 0xee, 0xd0, 0x06, 0xf3, 0x40, 0x0f, 0xe1, 0x30, 0x0e, 0xeb,
0x00, 0x10, 0xf3, 0x40, 0x0f, 0xe1, 0x30, 0x0e, 0xeb, 0xd0, 0x06, 0xf0, 0x20, 0x0f, 0xef, 0x40, 0x0f, 0xe5, 0x30, 0x0e, 0xf4, 0xf0, 0x0e, 0xf2, 0xd0, 0x06, 0xe2, 0x50, 0x0f, 0xe6, 0x60, 0x0e,
0xe5, 0x20, 0x0f, 0x6d, 0x30, 0x0f, 0xe9, 0xa0, 0x0f, 0xe5, 0x00, 0xc0, 0x01, 0x40, 0xd4, 0x83, 0x3b, 0xcc, 0x43, 0x38, 0x98, 0x43, 0x39, 0xb4, 0x81, 0x39, 0xc0, 0x43, 0x1b, 0xb4, 0x43, 0x38,
0xd0, 0x03, 0x3a, 0x00, 0xe6, 0x10, 0x0e, 0xec, 0x30, 0x0f, 0xe5, 0x00, 0x10, 0xf5, 0x30, 0x0f, 0xe5, 0xd0, 0x06, 0xf3, 0xf0, 0x0e, 0xe6, 0x40, 0x0f, 0x6d, 0x60, 0x0e, 0xec, 0xf0, 0x0e, 0xe1,
0x40, 0x0f, 0x80, 0x39, 0x84, 0x03, 0x3b, 0xcc, 0x43, 0x39, 0x00, 0x1b, 0x8c, 0x41, 0x00, 0x16, 0x80, 0xda, 0x20, 0x1e, 0xc4, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x40, 0x04, 0x48, 0x04, 0x39, 0xa4,
0xc3, 0x3c, 0x84, 0x83, 0x38, 0xb0, 0x43, 0x39, 0xb4, 0x01, 0x3d, 0x84, 0x43, 0x3a, 0xb0, 0x43, 0x1b, 0x8c, 0x43, 0x38, 0xb0, 0x03, 0x3b, 0xcc, 0x03, 0x60, 0x0e, 0xe1, 0xc0, 0x0e, 0xf3, 0x50,
0x0e, 0x00, 0xc1, 0x0e, 0xe5, 0x30, 0x0f, 0xf3, 0xd0, 0x06, 0xf0, 0x20, 0x0f, 0xe5, 0x30, 0x0e, 0xe9, 0x30, 0x0f, 0xe5, 0xd0, 0x06, 0xe6, 0x00, 0x0f, 0xed, 0x10, 0x0e, 0xe4, 0x00, 0x98, 0x43,
0x38, 0xb0, 0xc3, 0x3c, 0x94, 0x03, 0x40, 0xb8, 0xc3, 0x3b, 0xb4, 0x81, 0x39, 0xc8, 0x43, 0x38, 0xb4, 0x43, 0x39, 0xb4, 0x01, 0x3c, 0xbc, 0x43, 0x3a, 0xb8, 0x03, 0x3d, 0x94, 0x83, 0x3c, 0xb4,
0x41, 0x39, 0xb0, 0x43, 0x3a, 0xb4, 0x03, 0x60, 0x0e, 0xe1, 0xc0, 0x0e, 0xf3, 0x50, 0x0e, 0x00, 0xe1, 0x0e, 0xef, 0xd0, 0x06, 0xe9, 0xe0, 0x0e, 0xe6, 0x30, 0x0f, 0x6d, 0x60, 0x0e, 0xf0, 0xd0,
0x06, 0xed, 0x10, 0x0e, 0xf4, 0x80, 0x0e, 0x80, 0x39, 0x84, 0x03, 0x3b, 0xcc, 0x43, 0x39, 0x00, 0x84, 0x3b, 0xbc, 0x43, 0x1b, 0xb8, 0x43, 0x38, 0xb8, 0xc3, 0x3c, 0xb4, 0x81, 0x39, 0xc0, 0x43,
0x1b, 0xb4, 0x43, 0x38, 0xd0, 0x03, 0x3a, 0x00, 0xe6, 0x10, 0x0e, 0xec, 0x30, 0x0f, 0xe5, 0x00, 0x0c, 0xee, 0xf0, 0x0e, 0x6d, 0x20, 0x0f, 0xe5, 0x10, 0x0e, 0xec, 0x90, 0x0e, 0xe7, 0xe0, 0x0e,
0x6d, 0x30, 0x0f, 0xf4, 0x10, 0x0e, 0xe3, 0xb0, 0x0e, 0x00, 0x31, 0x0f, 0xf4, 0x10, 0x0e, 0xe3, 0xb0, 0x0e, 0x6d, 0x00, 0x0f, 0xf2, 0xf0, 0x0e, 0xf4, 0x50, 0x0e, 0xe3, 0x40, 0x0f, 0xef, 0x20,
0x0f, 0x6d, 0x20, 0x0e, 0xf5, 0x60, 0x0e, 0xe6, 0x50, 0x0e, 0xf2, 0xd0, 0x06, 0xf3, 0x90, 0x0e, 0xfa, 0x50, 0x0e, 0x00, 0x1c, 0x00, 0x44, 0x3d, 0xb8, 0xc3, 0x3c, 0x84, 0x83, 0x39, 0x94, 0x43,
0x1b, 0x98, 0x03, 0x3c, 0xb4, 0x41, 0x3b, 0x84, 0x03, 0x3d, 0xa0, 0x03, 0x60, 0x0e, 0xe1, 0xc0, 0x0e, 0xf3, 0x50, 0x0e, 0x00, 0x51, 0x0f, 0xf3, 0x50, 0x0e, 0x6d, 0x30, 0x0f, 0xef, 0x60, 0x0e,
0xf4, 0xd0, 0x06, 0xe6, 0xc0, 0x0e, 0xef, 0x10, 0x0e, 0xf4, 0x00, 0x98, 0x43, 0x38, 0xb0, 0xc3, 0x3c, 0x94, 0x03, 0xb0, 0xc1, 0x28, 0x04, 0x60, 0x01, 0xaa, 0x0d, 0x86, 0xf1, 0xff, 0xff, 0xff,
0xff, 0x03, 0x10, 0x01, 0xd2, 0x06, 0xe2, 0xf8, 0xff, 0xff, 0xff, 0xff, 0x01, 0x90, 0x36, 0x18, 0xc8, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x80, 0x04, 0x50, 0x1b, 0x8c, 0xe4, 0xff, 0xff, 0xff, 0xff,
0x07, 0x40, 0x02, 0xaa, 0x0d, 0x84, 0x42, 0x00, 0x67, 0xb0, 0x81, 0x58, 0x20, 0xe0, 0x0c, 0x00, 0x49, 0x18, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x13, 0x84, 0x40, 0x98, 0x30, 0x04, 0x83, 0x30,
0x61, 0x08, 0x06, 0x62, 0xc2, 0x10, 0x14, 0xc4, 0x84, 0x40, 0x98, 0x10, 0x18, 0x13, 0x82, 0x63, 0x42, 0x80, 0x4c, 0x08, 0x92, 0x09, 0x81, 0x32, 0x21, 0x58, 0x00, 0x00, 0x89, 0x20, 0x00, 0x00,
0x88, 0x00, 0x00, 0x00, 0x32, 0x22, 0xc8, 0x09, 0x20, 0x64, 0x85, 0x04, 0x93, 0x23, 0xa4, 0x84, 0x04, 0x93, 0x23, 0xe3, 0x84, 0xa1, 0x90, 0x14, 0x12, 0x4c, 0x8e, 0x8c, 0x0b, 0x84, 0xe4, 0x4c,
0x10, 0x94, 0xc2, 0x1c, 0x01, 0x18, 0x9c, 0x19, 0x48, 0x53, 0x44, 0x09, 0x93, 0xbf, 0x02, 0xd8, 0x14, 0x01, 0x02, 0xd2, 0x18, 0x9a, 0x20, 0x10, 0x0b, 0x11, 0x01, 0x13, 0xe2, 0x34, 0xec, 0x14,
0x51, 0xc2, 0x44, 0x45, 0x04, 0x0a, 0x00, 0x14, 0x98, 0x01, 0x18, 0x46, 0x10, 0x86, 0x99, 0xd2, 0x60, 0x1c, 0xd8, 0x21, 0x1c, 0xe6, 0x61, 0x1e, 0xdc, 0x60, 0x16, 0xe8, 0x41, 0x1e, 0xea, 0x61,
0x1c, 0xe8, 0xa1, 0x1e, 0xe4, 0xa1, 0x1c, 0xc8, 0x41, 0x14, 0xea, 0xc1, 0x1c, 0xcc, 0xa1, 0x1c, 0xe4, 0x81, 0x0f, 0xec, 0xa1, 0x1c, 0xc6, 0x81, 0x1e, 0xde, 0x41, 0x1e, 0xf8, 0xc0, 0x1c, 0xd8,
0xe1, 0x1d, 0xc2, 0x81, 0x1e, 0xd8, 0x00, 0x0c, 0xe4, 0xc0, 0x0f, 0xc0, 0xc0, 0x0f, 0x50, 0x40, 0xa0, 0xc2, 0x4c, 0x6b, 0x30, 0x0e, 0xec, 0x10, 0x0e, 0xf3, 0x30, 0x0f, 0x6e, 0x20, 0x0b, 0xb7,
0x30, 0x0b, 0xf4, 0x20, 0x0f, 0xf5, 0x30, 0x0e, 0xf4, 0x50, 0x0f, 0xf2, 0x50, 0x0e, 0xe4, 0x20, 0x0a, 0xf5, 0x60, 0x0e, 0xe6, 0x50, 0x0e, 0xf2, 0xc0, 0x07, 0xf6, 0x50, 0x0e, 0xe3, 0x40, 0x0f,
0xef, 0x20, 0x0f, 0x7c, 0x60, 0x0e, 0xec, 0xf0, 0x0e, 0xe1, 0x40, 0x0f, 0x6c, 0x00, 0x06, 0x72, 0xe0, 0x07, 0x60, 0xe0, 0x07, 0x28, 0x20, 0xd0, 0xe1, 0x9c, 0xd2, 0x11, 0x80, 0x85, 0x73, 0x1a,
0x69, 0x02, 0x9a, 0x49, 0x42, 0xc1, 0x80, 0x12, 0xf7, 0x94, 0x8e, 0x00, 0x2c, 0x9c, 0xd3, 0x48, 0x13, 0xd0, 0x4c, 0x92, 0x8d, 0x82, 0x01, 0x2d, 0xae, 0xf8, 0x16, 0xc0, 0x90, 0x50, 0x00, 0xa0,
0xc6, 0x08, 0xc0, 0x45, 0xd2, 0x14, 0x51, 0xc2, 0xe4, 0xaf, 0x00, 0x96, 0x02, 0xd8, 0xe2, 0x00, 0x03, 0x0a, 0x08, 0x04, 0x29, 0xc2, 0x23, 0x42, 0x92, 0x63, 0x03, 0x69, 0x8a, 0x28, 0x61, 0xf2,
0x37, 0x0a, 0x59, 0x26, 0xb1, 0x69, 0x23, 0x04, 0x68, 0x8c, 0x85, 0x10, 0x9b, 0x89, 0x88, 0x24, 0x42, 0x98, 0x10, 0xa7, 0xd1, 0xa6, 0x29, 0x42, 0x02, 0x6a, 0x22, 0x24, 0x14, 0x10, 0x88, 0x52,
0x86, 0x47, 0xa4, 0x42, 0x96, 0x93, 0xa4, 0x29, 0xa2, 0x84, 0xc9, 0xd7, 0xb4, 0x6d, 0xd3, 0xa6, 0x29, 0x42, 0x02, 0x09, 0x05, 0x03, 0xc2, 0x94, 0xe1, 0x11, 0xc9, 0x90, 0xa6, 0x04, 0x0f, 0xe2,
0x14, 0xe1, 0x01, 0x20, 0xcf, 0x1c, 0x41, 0x50, 0x0a, 0x10, 0x60, 0x00, 0xc8, 0x50, 0x68, 0x8e, 0x00, 0x29, 0x03, 0x00, 0x30, 0x22, 0x12, 0x8d, 0xee, 0x19, 0x2e, 0x7f, 0xc2, 0x1e, 0x42, 0xf2,
0x43, 0xa0, 0x19, 0x16, 0x02, 0x05, 0xa6, 0xb2, 0x3c, 0x00, 0x27, 0x00, 0x60, 0x30, 0x18, 0x0c, 0x46, 0x00, 0x42, 0xdd, 0x34, 0x5c, 0xfe, 0x84, 0x3d, 0x84, 0xe4, 0xaf, 0x84, 0xb4, 0x12, 0x93,
0x5f, 0xdc, 0x36, 0x2a, 0x06, 0x83, 0xc1, 0x00, 0x50, 0x0e, 0x15, 0xe0, 0x04, 0x00, 0x8c, 0x00, 0xb4, 0x2a, 0xd1, 0x03, 0x70, 0x02, 0x00, 0x00, 0x00, 0xc0, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x83,
0x41, 0x84, 0x5a, 0x47, 0x0d, 0x97, 0x3f, 0x61, 0x0f, 0x21, 0xf9, 0xdc, 0x46, 0x15, 0x2b, 0x31, 0xf9, 0xc5, 0x6d, 0x23, 0x62, 0x30, 0x18, 0x0c, 0x0a, 0xf1, 0x02, 0x9c, 0x00, 0x04, 0x3b, 0x6a,
0xb8, 0xfc, 0x09, 0x7b, 0x08, 0xc9, 0xe7, 0x36, 0xaa, 0x58, 0x89, 0xc9, 0x47, 0x6e, 0x1b, 0x11, 0x00, 0x00, 0x00, 0x50, 0x08, 0x19, 0xe0, 0x04, 0xa0, 0x59, 0x19, 0x4e, 0x80, 0x04, 0xd5, 0xca,
0x70, 0x02, 0x2c, 0xe8, 0x56, 0x86, 0x13, 0xa0, 0x41, 0xb9, 0x32, 0x9c, 0x00, 0x05, 0xda, 0x95, 0xe1, 0x04, 0x08, 0x50, 0xaf, 0x0c, 0x27, 0xc0, 0x81, 0x7e, 0x03, 0x01, 0x73, 0x04, 0xa0, 0x40,
0x04, 0x1a, 0x00, 0x00, 0x13, 0x14, 0x72, 0xc0, 0x87, 0x74, 0x60, 0x87, 0x36, 0x68, 0x87, 0x79, 0x68, 0x03, 0x72, 0xc0, 0x87, 0x0d, 0xaf, 0x50, 0x0e, 0x6d, 0xd0, 0x0e, 0x7a, 0x50, 0x0e, 0x6d,
0x00, 0x0f, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x71, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x78, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e,
0x71, 0x60, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, 0xe9, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xe6, 0x10,
0x07, 0x76, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x60, 0x0e, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, 0xe6, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, 0xe0, 0x0e, 0x78,
0xa0, 0x07, 0x71, 0x60, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x3a, 0x0f, 0x84, 0x90, 0x21, 0x23, 0x45, 0x44, 0x00, 0xc6, 0x00, 0x80, 0x59, 0x03, 0x00, 0xe6, 0x0d, 0x00,
0x98, 0x39, 0x00, 0x00, 0xee, 0x00, 0x00, 0xd8, 0x03, 0x00, 0x18, 0xf2, 0x48, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0xe4, 0xb1, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x60, 0xc8, 0x63, 0x01, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x90, 0x47, 0x03, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x21,
0x0f, 0x07, 0x00, 0x40, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43, 0x1e, 0x0e, 0x00, 0x80, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86, 0x3c, 0x1e, 0x10, 0x00, 0x06, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x79, 0xc2, 0x00, 0x08, 0x80, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86, 0x3c, 0x64, 0x00, 0x04, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x43, 0x1e, 0x34, 0x00, 0x02, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x21, 0xcf, 0x1a, 0x00, 0x01, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x90, 0xa7,
0x0d, 0x80, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0xc8, 0x03, 0x07, 0x40, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0xe4, 0x99, 0x03, 0x20, 0x00, 0x12,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xf2, 0xd4, 0x01, 0x10, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x79, 0xee, 0x00, 0x08, 0x80, 0x04, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x86, 0x3c, 0x79, 0x00, 0x04, 0x40, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43, 0x9e, 0x3d, 0x00, 0x02, 0x20, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x21,
0x4f, 0x1f, 0x00, 0x01, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x90, 0xe7, 0x0f, 0x80, 0x00, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x0b, 0x04, 0x00, 0x00, 0x00,
0x0d, 0x00, 0x00, 0x00, 0x32, 0x1e, 0x98, 0x18, 0x19, 0x11, 0x4c, 0x90, 0x8c, 0x09, 0x26, 0x47, 0xc6, 0x04, 0x43, 0x02, 0x94, 0x40, 0x19, 0x14, 0xc3, 0x08, 0x40, 0x81, 0x14, 0x42, 0x61, 0x14,
0x44, 0x11, 0x94, 0x44, 0x39, 0x94, 0x42, 0x51, 0x94, 0x05, 0x81, 0x46, 0x00, 0x48, 0x58, 0xa0, 0x80, 0x08, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x79, 0x18, 0x00, 0x00, 0xee, 0x00, 0x00, 0x00,
0x1a, 0x03, 0x4c, 0x90, 0x46, 0x02, 0x13, 0x44, 0x35, 0x18, 0x63, 0x0b, 0x73, 0x3b, 0x03, 0xb1, 0x2b, 0x93, 0x9b, 0x4b, 0x7b, 0x73, 0x03, 0x99, 0x71, 0xb9, 0x01, 0x41, 0xa1, 0x0b, 0x3b, 0x9b,
0x7b, 0x91, 0x2a, 0x62, 0x2a, 0x0a, 0x9a, 0x2a, 0xfa, 0x9a, 0xb9, 0x81, 0x79, 0x31, 0x4b, 0x73, 0x0b, 0x63, 0x4b, 0xd9, 0x10, 0x04, 0x13, 0x04, 0x40, 0x9b, 0x20, 0x00, 0xdb, 0x06, 0x61, 0x20,
0x26, 0x08, 0x00, 0xb7, 0x41, 0x18, 0x0c, 0x0e, 0x6c, 0x69, 0x62, 0x1b, 0x06, 0xc4, 0x20, 0x26, 0x08, 0x40, 0x37, 0x41, 0x10, 0x00, 0x0a, 0x41, 0x53, 0x13, 0x04, 0xc0, 0x9b, 0x20, 0x00, 0xdf,
0x06, 0x41, 0x71, 0x36, 0x24, 0xca, 0xc2, 0x28, 0xca, 0xd0, 0x28, 0xcf, 0x04, 0xc1, 0x08, 0xc8, 0x48, 0x85, 0xe5, 0x41, 0xbd, 0xcd, 0xa5, 0xd1, 0xa5, 0xbd, 0xb9, 0xcd, 0x4d, 0x10, 0x00, 0x30,
0x98, 0x20, 0x00, 0x61, 0xb0, 0x41, 0x18, 0xa8, 0x0d, 0xc9, 0x10, 0x49, 0xca, 0x30, 0x4c, 0x4a, 0xb5, 0x41, 0x80, 0xac, 0x09, 0x02, 0x22, 0x70, 0x10, 0xaa, 0x33, 0x9b, 0x20, 0x80, 0x01, 0x1a,
0x6c, 0x58, 0x14, 0x2c, 0x53, 0x94, 0x61, 0xd2, 0x34, 0xad, 0xda, 0x10, 0x6c, 0x13, 0x04, 0x65, 0xa0, 0xc3, 0xf4, 0x36, 0x16, 0xc6, 0x36, 0xf4, 0xe6, 0x36, 0x47, 0x17, 0xe6, 0x46, 0x37, 0xb7,
0x01, 0x51, 0x3a, 0x6f, 0x50, 0x06, 0x07, 0x98, 0x20, 0x30, 0x04, 0x1f, 0xa6, 0xb7, 0xb1, 0x30, 0xb6, 0xa1, 0x37, 0xb7, 0x39, 0xba, 0x30, 0x37, 0xba, 0x39, 0x99, 0x0d, 0xc8, 0x00, 0x06, 0x61,
0x30, 0x0c, 0x83, 0x03, 0x4c, 0x10, 0x00, 0x31, 0x98, 0x20, 0x38, 0x05, 0x0b, 0x23, 0xb6, 0xb0, 0xb3, 0xb9, 0x0d, 0xc8, 0x18, 0x90, 0x41, 0x19, 0x28, 0xca, 0xe0, 0x00, 0x1b, 0x86, 0x4f, 0x0c,
0xcc, 0x60, 0x03, 0x71, 0x71, 0x67, 0x00, 0x4c, 0x10, 0x26, 0x63, 0x03, 0xb0, 0x61, 0x18, 0xd4, 0x40, 0x0d, 0x36, 0x0c, 0x63, 0xa0, 0x06, 0x6a, 0xb0, 0x41, 0x58, 0x03, 0x36, 0x98, 0x20, 0x5c,
0xc7, 0x86, 0x41, 0x51, 0x03, 0x35, 0xd8, 0x30, 0xac, 0x01, 0x1b, 0xbc, 0xc1, 0x04, 0xe1, 0x42, 0x26, 0x08, 0x5b, 0x32, 0x41, 0xe8, 0x94, 0x0d, 0xc1, 0x1a, 0x4c, 0x10, 0xba, 0x65, 0x43, 0x33,
0xa4, 0x41, 0x1b, 0xb8, 0x01, 0x1c, 0xc4, 0x01, 0x1c, 0xc8, 0x01, 0x1c, 0xcc, 0x01, 0x1d, 0xd4, 0x01, 0x1d, 0x10, 0x98, 0x20, 0x88, 0x42, 0x1a, 0x6c, 0x10, 0x14, 0x3c, 0xd8, 0x50, 0x00, 0x77,
0x00, 0xa0, 0x41, 0x1e, 0xd0, 0x0d, 0x02, 0x7e, 0xa4, 0xc2, 0xf2, 0x82, 0xdc, 0xf2, 0x82, 0x82, 0x84, 0x84, 0x80, 0x80, 0xb2, 0x82, 0xb0, 0xaa, 0xa4, 0xc2, 0xf2, 0xa0, 0xc2, 0xf2, 0xd8, 0xde,
0xc2, 0xc8, 0x80, 0x80, 0xaa, 0x82, 0x82, 0x84, 0x84, 0x82, 0xe8, 0xe8, 0xe4, 0xd2, 0xc4, 0xe6, 0x80, 0x80, 0x80, 0xb4, 0x26, 0x08, 0xc0, 0x18, 0x4c, 0x10, 0x00, 0x32, 0x98, 0x20, 0x00, 0x65,
0xb0, 0x21, 0x50, 0x36, 0x20, 0x14, 0x1f, 0x18, 0x54, 0x1f, 0x38, 0x7e, 0xf0, 0x07, 0x1b, 0x0a, 0x39, 0xd8, 0x03, 0x00, 0x00, 0x05, 0xb2, 0x42, 0xc0, 0x8f, 0x54, 0x58, 0x5e, 0x90, 0x5b, 0x1e,
0x95, 0x5c, 0x5a, 0x98, 0xdb, 0x19, 0x5b, 0x19, 0x10, 0x50, 0x56, 0x10, 0x56, 0x95, 0x54, 0x58, 0x1e, 0x54, 0x58, 0x1e, 0xdb, 0x5b, 0x18, 0x19, 0x10, 0x50, 0x95, 0x50, 0x5d, 0x1a, 0x1b, 0x5d,
0x92, 0x1b, 0x95, 0x5c, 0x5a, 0x98, 0xdb, 0x19, 0x5b, 0x59, 0x92, 0x1b, 0x5d, 0x99, 0xdc, 0x5c, 0xd9, 0x18, 0x5d, 0xda, 0x9b, 0x5b, 0x10, 0x1d, 0x9d, 0x5c, 0x9a, 0x58, 0x1d, 0x5d, 0xd9, 0x1c,
0x10, 0x10, 0x90, 0xd6, 0x06, 0x84, 0xe2, 0x03, 0x83, 0xea, 0x03, 0xca, 0x0f, 0xfe, 0x60, 0x43, 0x11, 0x07, 0xa2, 0x00, 0x00, 0xa3, 0x40, 0x54, 0x08, 0xf8, 0x91, 0x0a, 0xcb, 0x1b, 0x62, 0x7b,
0x9b, 0x2b, 0x9b, 0xa3, 0x03, 0x02, 0xca, 0x0a, 0xc2, 0xaa, 0x92, 0x0a, 0xcb, 0x83, 0x0a, 0xcb, 0x63, 0x7b, 0x0b, 0x23, 0x03, 0x02, 0xaa, 0x12, 0xaa, 0x4b, 0x63, 0xa3, 0x4b, 0x72, 0xa3, 0x92,
0x4b, 0x0b, 0x73, 0x3b, 0x63, 0x2b, 0x4b, 0x72, 0xa3, 0x2b, 0x93, 0x9b, 0x2b, 0x1b, 0xa3, 0x4b, 0x7b, 0x73, 0x0b, 0xa2, 0xa3, 0x93, 0x4b, 0x13, 0xab, 0xa3, 0x2b, 0x9b, 0x03, 0x02, 0x02, 0xd2,
0x9a, 0x20, 0x00, 0x66, 0xb0, 0x01, 0xa1, 0x4c, 0xc1, 0xa0, 0xfa, 0x80, 0xf2, 0x83, 0x3f, 0xd8, 0x50, 0xb8, 0x41, 0x29, 0x00, 0xc0, 0x29, 0xf0, 0x09, 0xf8, 0x91, 0x0a, 0xcb, 0x3b, 0x2a, 0x73,
0x03, 0x02, 0xca, 0x0a, 0xc2, 0xc2, 0xd2, 0xda, 0x40, 0x50, 0x7d, 0xe0, 0x07, 0x7f, 0xb0, 0xa1, 0xa8, 0x83, 0x54, 0x00, 0x00, 0x55, 0x60, 0x15, 0xf0, 0x23, 0x15, 0x96, 0x97, 0xe4, 0x46, 0x57,
0x26, 0x37, 0x57, 0x36, 0x46, 0x07, 0x04, 0x94, 0x15, 0x84, 0x85, 0xa5, 0xb5, 0x81, 0xa0, 0x28, 0x3f, 0xf8, 0x83, 0x0d, 0xc5, 0x1c, 0xb0, 0x02, 0x00, 0xb4, 0x02, 0xbb, 0x80, 0x1f, 0xa9, 0xb0,
0xbc, 0xa6, 0xb4, 0xb9, 0x39, 0x20, 0xa0, 0xac, 0x20, 0xac, 0x2a, 0xa9, 0xb0, 0x3c, 0xa8, 0xb0, 0x3c, 0xb6, 0xb7, 0x30, 0x32, 0x20, 0x20, 0x20, 0xad, 0x09, 0x02, 0x70, 0x06, 0x1b, 0x0c, 0x0a,
0x16, 0x0c, 0xca, 0x0f, 0xfe, 0x60, 0x43, 0x91, 0x06, 0xaf, 0x00, 0x00, 0xb1, 0xc0, 0xc2, 0x8c, 0xed, 0x2d, 0x8c, 0x8e, 0xcf, 0x5b, 0x9b, 0x5b, 0x1a, 0xdc, 0x1b, 0x5d, 0x99, 0x1b, 0x1d, 0xc8,
0x18, 0x5a, 0x98, 0x1c, 0xa3, 0xa9, 0xb4, 0x36, 0x38, 0xb6, 0x32, 0x90, 0xa1, 0x97, 0xa1, 0x95, 0x15, 0x10, 0x2a, 0xa1, 0xa0, 0xa0, 0x0d, 0x41, 0x2d, 0x4c, 0x10, 0x44, 0x41, 0x0d, 0x36, 0x0c,
0xb4, 0x60, 0x0b, 0xb7, 0xb0, 0x61, 0x98, 0x05, 0x5c, 0xb8, 0x85, 0x0d, 0x43, 0x2e, 0xe4, 0xc2, 0x2d, 0x6c, 0x18, 0x70, 0x01, 0x17, 0x6e, 0xa1, 0x0a, 0x1b, 0x9b, 0x5d, 0x9b, 0x4b, 0x1a, 0x59,
0x99, 0x1b, 0xdd, 0x94, 0x20, 0xa8, 0x42, 0x86, 0xe7, 0x62, 0x57, 0x26, 0x37, 0x97, 0xf6, 0xe6, 0x36, 0x25, 0x20, 0x9a, 0x90, 0xe1, 0xb9, 0xd8, 0x85, 0xb1, 0xd9, 0x95, 0xc9, 0x4d, 0x09, 0x8c,
0x3a, 0x64, 0x78, 0x2e, 0x73, 0x68, 0x61, 0x64, 0x65, 0x72, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x53, 0x02, 0xa4, 0x0c, 0x19, 0x9e, 0x8b, 0x5c, 0xd9, 0xdc, 0x5b, 0x9d, 0xdc, 0x58, 0xd9, 0xdc, 0x94,
0xe0, 0x0c, 0x2a, 0x91, 0xe1, 0xb9, 0xd0, 0xe5, 0xc1, 0x95, 0x05, 0xb9, 0xb9, 0xbd, 0xd1, 0x85, 0xd1, 0xa5, 0xbd, 0xb9, 0xcd, 0x4d, 0x09, 0xea, 0xa0, 0x0e, 0x19, 0x9e, 0x4b, 0x99, 0x1b, 0x9d,
0x5c, 0x1e, 0xd4, 0x5b, 0x9a, 0x1b, 0xdd, 0xdc, 0x94, 0x23, 0x0f, 0x40, 0x61, 0x14, 0x4e, 0x41, 0x15, 0x5a, 0x21, 0x16, 0x00, 0x00, 0x00, 0x00, 0x79, 0x18, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00,
0x33, 0x08, 0x80, 0x1c, 0xc4, 0xe1, 0x1c, 0x66, 0x14, 0x01, 0x3d, 0x88, 0x43, 0x38, 0x84, 0xc3, 0x8c, 0x42, 0x80, 0x07, 0x79, 0x78, 0x07, 0x73, 0x98, 0x71, 0x0c, 0xe6, 0x00, 0x0f, 0xed, 0x10,
0x0e, 0xf4, 0x80, 0x0e, 0x33, 0x0c, 0x42, 0x1e, 0xc2, 0xc1, 0x1d, 0xce, 0xa1, 0x1c, 0x66, 0x30, 0x05, 0x3d, 0x88, 0x43, 0x38, 0x84, 0x83, 0x1b, 0xcc, 0x03, 0x3d, 0xc8, 0x43, 0x3d, 0x8c, 0x03,
0x3d, 0xcc, 0x78, 0x8c, 0x74, 0x70, 0x07, 0x7b, 0x08, 0x07, 0x79, 0x48, 0x87, 0x70, 0x70, 0x07, 0x7a, 0x70, 0x03, 0x76, 0x78, 0x87, 0x70, 0x20, 0x87, 0x19, 0xcc, 0x11, 0x0e, 0xec, 0x90, 0x0e,
0xe1, 0x30, 0x0f, 0x6e, 0x30, 0x0f, 0xe3, 0xf0, 0x0e, 0xf0, 0x50, 0x0e, 0x33, 0x10, 0xc4, 0x1d, 0xde, 0x21, 0x1c, 0xd8, 0x21, 0x1d, 0xc2, 0x61, 0x1e, 0x66, 0x30, 0x89, 0x3b, 0xbc, 0x83, 0x3b,
0xd0, 0x43, 0x39, 0xb4, 0x03, 0x3c, 0xbc, 0x83, 0x3c, 0x84, 0x03, 0x3b, 0xcc, 0xf0, 0x14, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x68, 0x87, 0x72, 0x68, 0x07, 0x37, 0x80, 0x87, 0x70, 0x90,
0x87, 0x70, 0x60, 0x07, 0x76, 0x28, 0x07, 0x76, 0xf8, 0x05, 0x76, 0x78, 0x87, 0x77, 0x80, 0x87, 0x5f, 0x08, 0x87, 0x71, 0x18, 0x87, 0x72, 0x98, 0x87, 0x79, 0x98, 0x81, 0x2c, 0xee, 0xf0, 0x0e,
0xee, 0xe0, 0x0e, 0xf5, 0xc0, 0x0e, 0xec, 0x30, 0x03, 0x62, 0xc8, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xcc, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xdc, 0x61, 0x1c, 0xca, 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca,
0x61, 0x06, 0xd6, 0x90, 0x43, 0x39, 0xc8, 0x43, 0x39, 0x98, 0x43, 0x39, 0xc8, 0x43, 0x39, 0xb8, 0xc3, 0x38, 0x94, 0x43, 0x38, 0x88, 0x03, 0x3b, 0x94, 0xc3, 0x2f, 0xbc, 0x83, 0x3c, 0xfc, 0x82,
0x3b, 0xd4, 0x03, 0x3b, 0xb0, 0xc3, 0x8c, 0xc8, 0x21, 0x07, 0x7c, 0x70, 0x03, 0x72, 0x10, 0x87, 0x73, 0x70, 0x03, 0x7b, 0x08, 0x07, 0x79, 0x60, 0x87, 0x70, 0xc8, 0x87, 0x77, 0xa8, 0x07, 0x7a,
0x00, 0x00, 0x00, 0x00, 0x71, 0x20, 0x00, 0x00, 0xd6, 0x00, 0x00, 0x00, 0x05, 0xa0, 0x06, 0x81, 0x5f, 0x70, 0x0a, 0x04, 0xce, 0xaa, 0xd2, 0x70, 0x9e, 0x2e, 0x0f, 0x8f, 0xd3, 0xee, 0x73, 0x70,
0x3c, 0x2e, 0xb3, 0xcb, 0xf2, 0x30, 0x3d, 0xfd, 0x76, 0x4f, 0xe9, 0xf2, 0xfa, 0x98, 0x5e, 0x97, 0x97, 0x81, 0xc0, 0x60, 0x09, 0xc4, 0x41, 0xe0, 0x27, 0xac, 0x9b, 0x81, 0xc0, 0x99, 0xf5, 0x47,
0x92, 0x5e, 0xa7, 0x74, 0x79, 0x7d, 0x4c, 0xaf, 0xcb, 0xcb, 0x64, 0x61, 0xdd, 0x6c, 0x2e, 0xcb, 0x81, 0xd6, 0x1f, 0xc9, 0x5e, 0x1e, 0xd3, 0xdf, 0x72, 0x60, 0x93, 0x04, 0x8b, 0x01, 0x81, 0x40,
0x60, 0xb0, 0x12, 0xdc, 0x20, 0xf0, 0x93, 0x86, 0xf3, 0x41, 0x77, 0x3e, 0x18, 0x14, 0x0a, 0x81, 0xc0, 0x6c, 0x10, 0x5b, 0x95, 0x86, 0xf3, 0xd0, 0x70, 0x9e, 0xfd, 0x0e, 0x93, 0x81, 0xc0, 0x6a,
0x30, 0x28, 0x14, 0x06, 0xe9, 0x74, 0x79, 0x5a, 0x3c, 0x07, 0x02, 0x81, 0xda, 0x42, 0x60, 0x85, 0xc0, 0x4f, 0x1a, 0xce, 0x07, 0xdd, 0x79, 0xaa, 0x3c, 0x1d, 0x76, 0x9f, 0xd9, 0x65, 0x20, 0x30,
0x1b, 0xc4, 0x56, 0xa5, 0xe1, 0x3c, 0x34, 0x9c, 0x67, 0xbf, 0xc3, 0x64, 0x20, 0xb0, 0x2a, 0xac, 0xa7, 0xd9, 0xf4, 0xa4, 0x9b, 0x2a, 0x4f, 0x87, 0xdd, 0x67, 0x76, 0x39, 0xe9, 0xa6, 0x97, 0xe5,
0xf3, 0xf2, 0x98, 0x9e, 0x7e, 0xbb, 0x83, 0x74, 0xba, 0x3c, 0x2d, 0xae, 0xd3, 0xcb, 0x73, 0x20, 0x10, 0xa8, 0xad, 0x03, 0x54, 0x08, 0xfc, 0xa4, 0xe1, 0xfc, 0x90, 0xfd, 0x9e, 0x97, 0xe7, 0x74,
0x20, 0x30, 0x1b, 0xc4, 0x56, 0xa5, 0xe1, 0x3c, 0x34, 0x9c, 0x67, 0xbf, 0xc3, 0x64, 0x20, 0xb0, 0x2a, 0xac, 0xa7, 0xd9, 0xf4, 0xa4, 0x9b, 0x2a, 0x4f, 0x87, 0xdd, 0x67, 0x76, 0x39, 0xe9, 0xa6,
0x97, 0xe5, 0xf3, 0xf2, 0x98, 0x9e, 0x7e, 0xbb, 0x83, 0x74, 0xba, 0x3c, 0x2d, 0xae, 0xd3, 0xcb, 0x73, 0x20, 0x10, 0xa8, 0xad, 0x85, 0x27, 0xf0, 0x93, 0x86, 0xf3, 0xc7, 0xb2, 0x1b, 0x08, 0xcc,
0x06, 0xb1, 0x58, 0x6d, 0x29, 0x54, 0x81, 0x9f, 0x34, 0x9c, 0x4f, 0xba, 0xe9, 0x65, 0xf9, 0xbc, 0x3c, 0xa6, 0x03, 0x81, 0xd9, 0x20, 0x16, 0xab, 0x2d, 0x83, 0x2e, 0xf0, 0x93, 0x86, 0xf3, 0xcd,
0xf4, 0x7c, 0x0e, 0x04, 0x66, 0x83, 0xd8, 0xaa, 0x34, 0x9c, 0x87, 0x86, 0xf3, 0xec, 0x77, 0x98, 0x0c, 0x04, 0x02, 0xb5, 0x15, 0x80, 0x07, 0x81, 0x9f, 0x34, 0x9c, 0x87, 0xbe, 0xe7, 0x69, 0x7a,
0xfa, 0xed, 0x9e, 0x03, 0x81, 0x33, 0xeb, 0x8f, 0x34, 0xa5, 0xcb, 0xeb, 0x63, 0x7a, 0x5d, 0x5e, 0x26, 0x0b, 0xeb, 0x66, 0x73, 0x59, 0x0e, 0xb4, 0xfe, 0x48, 0xf6, 0xf2, 0x98, 0xfe, 0x96, 0x03,
0x9b, 0x24, 0x58, 0x0c, 0x08, 0x04, 0x02, 0x83, 0x56, 0x50, 0x7c, 0x0b, 0x60, 0x48, 0x36, 0xe0, 0x94, 0x8e, 0x00, 0x2c, 0x9c, 0xd3, 0x48, 0x13, 0xd0, 0x4c, 0x92, 0x11, 0x3c, 0xa5, 0x23, 0x00,
0x0b, 0xe7, 0x34, 0xd2, 0x04, 0x34, 0x93, 0x64, 0x9b, 0xc4, 0x36, 0x5c, 0xbe, 0xf3, 0xf8, 0x42, 0x40, 0x15, 0x05, 0x11, 0x95, 0x0e, 0x30, 0x94, 0x84, 0x01, 0x08, 0x98, 0x5f, 0xdc, 0xb6, 0x4d,
0x6c, 0xc3, 0xe5, 0x3b, 0x8f, 0x2f, 0x04, 0x54, 0x51, 0x10, 0x51, 0xe9, 0x00, 0x43, 0x49, 0x18, 0x80, 0x80, 0xf9, 0xc8, 0x6d, 0x9b, 0x85, 0x37, 0x5c, 0xbe, 0xf3, 0xf8, 0x42, 0x44, 0x00, 0x13,
0x11, 0x02, 0xcd, 0xb0, 0x10, 0x9f, 0x13, 0x95, 0x48, 0xe0, 0x7f, 0x0b, 0x60, 0x48, 0x46, 0x71, 0x06, 0xc3, 0xe5, 0x3b, 0x8f, 0x2f, 0x44, 0x04, 0x30, 0x11, 0x21, 0xd0, 0x0c, 0x0b, 0xf1, 0x39,
0x51, 0x89, 0x04, 0x7e, 0xe9, 0x08, 0xc0, 0xc2, 0x39, 0x8d, 0x34, 0x01, 0xcd, 0x24, 0x59, 0x05, 0x1a, 0x0c, 0x97, 0xef, 0x3c, 0xbe, 0x10, 0x11, 0xc0, 0x44, 0x84, 0x40, 0x33, 0x2c, 0xc4, 0xe7,
0x44, 0x25, 0x12, 0xf8, 0xa5, 0x23, 0x00, 0x0b, 0xe7, 0x34, 0xd2, 0x04, 0x34, 0x93, 0x64, 0x57, 0x06, 0x29, 0x90, 0xf1, 0xae, 0x37, 0xdc, 0x35, 0x96, 0x97, 0xc3, 0xf4, 0x32, 0x32, 0xec, 0x26,
0xb3, 0xcb, 0xc6, 0xb7, 0x9c, 0x99, 0x16, 0xbb, 0xc6, 0xec, 0xf0, 0x7c, 0xee, 0x92, 0x5e, 0xa7, 0x74, 0x79, 0x7d, 0x4c, 0xaf, 0xcb, 0xcb, 0x64, 0x61, 0xdd, 0x6c, 0x2e, 0xcb, 0x79, 0xf6, 0xf2,
0x98, 0xfe, 0x96, 0xf3, 0xcc, 0xec, 0x77, 0x98, 0xce, 0x02, 0xc9, 0x7c, 0x20, 0x5f, 0x5d, 0x88, 0x02, 0x19, 0xef, 0x7a, 0xc3, 0x5d, 0x63, 0x79, 0x39, 0x4c, 0x2f, 0x23, 0xc3, 0x6e, 0x32, 0xbb,
0x6c, 0x7c, 0xcb, 0x99, 0x69, 0xb1, 0x6b, 0xcc, 0x0e, 0xcf, 0xe7, 0xae, 0x29, 0x5d, 0x5e, 0x1f, 0xd3, 0xeb, 0xf2, 0x32, 0x59, 0x58, 0x37, 0x9b, 0xcb, 0x72, 0x9e, 0xbd, 0x3c, 0xa6, 0xbf, 0xe5,
0x3c, 0x33, 0xfb, 0x1d, 0xa6, 0xb3, 0x40, 0x32, 0x1f, 0xc8, 0x67, 0x18, 0x7f, 0x30, 0x5c, 0xbe, 0xf3, 0xf8, 0x42, 0x44, 0x00, 0x13, 0x11, 0x02, 0xcd, 0xb0, 0x10, 0x9f, 0x13, 0x95, 0x48, 0xe0,
0x4b, 0x53, 0x44, 0x09, 0x93, 0xbf, 0x02, 0xd8, 0x14, 0x01, 0x02, 0xd2, 0x18, 0x9a, 0x20, 0x10, 0x0b, 0x11, 0x01, 0x13, 0xe2, 0x34, 0xec, 0x14, 0x51, 0xc2, 0x44, 0x45, 0x84, 0x39, 0x6c, 0xc3,
0xe5, 0x3b, 0x8f, 0x3f, 0x20, 0xd2, 0x03, 0x4c, 0xc2, 0xb1, 0x02, 0x98, 0x24, 0x36, 0x03, 0x71, 0xf9, 0xc8, 0x6d, 0x1b, 0xc3, 0x33, 0x5c, 0xbe, 0xf3, 0xf8, 0x88, 0xd1, 0x38, 0x11, 0x11, 0x22,
0x93, 0x41, 0x5c, 0xc3, 0xe5, 0x3b, 0x8f, 0x1f, 0x01, 0xd6, 0x46, 0x15, 0x05, 0x11, 0x95, 0x0e, 0x30, 0xf8, 0xc5, 0x6d, 0xdb, 0x03, 0x36, 0x5c, 0xbe, 0xf3, 0xf8, 0x11, 0x60, 0x6d, 0x54, 0x51,
0x10, 0x11, 0x3b, 0x39, 0x11, 0xe1, 0x17, 0xb7, 0x6d, 0x0d, 0x62, 0x30, 0x5c, 0xbe, 0xf3, 0xf8, 0x11, 0xf1, 0x38, 0xd1, 0x14, 0x22, 0x93, 0x2f, 0x4d, 0x11, 0x25, 0x4c, 0xbe, 0xa6, 0x6d, 0x9b,
0x36, 0x4d, 0x11, 0x12, 0x48, 0x16, 0x01, 0x06, 0xc3, 0xe5, 0x3b, 0x8f, 0x3f, 0x45, 0x80, 0x40, 0xac, 0x00, 0xe6, 0x4b, 0x53, 0x44, 0x09, 0x93, 0xbf, 0x02, 0x58, 0x0a, 0x60, 0x8b, 0x03, 0x0c,
0x00, 0x00, 0x00, 0x00, 0x61, 0x20, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x13, 0x04, 0x41, 0x2c, 0x10, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x28, 0x60, 0x81, 0xb2, 0x03, 0x00, 0x00,
0xa4, 0x06, 0x8b, 0x41, 0x6c, 0x90, 0x18, 0x23, 0x06, 0x06, 0x00, 0x82, 0x60, 0x70, 0x07, 0x1b, 0x21, 0x8c, 0x18, 0x18, 0x00, 0x08, 0x82, 0x41, 0x1d, 0x74, 0x85, 0x30, 0x62, 0x70, 0x00, 0x20,
0x08, 0x06, 0x70, 0x00, 0x06, 0x45, 0x50, 0x8d, 0x26, 0x04, 0xc0, 0x86, 0x0c, 0xc9, 0x75, 0x51, 0x40, 0x18, 0x63, 0x08, 0x41, 0x66, 0x01, 0x01, 0x9f, 0x0d, 0x21, 0x9a, 0x6d, 0xdb, 0x86, 0x0d,
0x88, 0x40, 0x18, 0x80, 0x11, 0x83, 0x03, 0x00, 0x41, 0x30, 0x80, 0x83, 0x33, 0x60, 0x12, 0x6e, 0x34, 0x21, 0x00, 0xe8, 0x20, 0x8c, 0x31, 0x84, 0x40, 0x0c, 0x2c, 0x18, 0xe0, 0xb3, 0x21, 0xc4,
0x14, 0x06, 0x61, 0x40, 0x06, 0xc3, 0x06, 0x44, 0x20, 0x0c, 0x00, 0x86, 0x03, 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0xb6, 0x72, 0x3c, 0x00, 0xb6, 0x38, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00,
0x61, 0x20, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x13, 0x04, 0x41, 0x2c, 0x10, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x28, 0x60, 0x81, 0xb2, 0x03, 0x00, 0x00, 0xb4, 0x06, 0x8b, 0x41,
0x6d, 0x90, 0x18, 0x23, 0x06, 0x06, 0x00, 0x82, 0x60, 0x70, 0x07, 0x1c, 0x21, 0x8c, 0x18, 0x18, 0x00, 0x08, 0x82, 0x41, 0x1d, 0x78, 0x85, 0x30, 0x62, 0x70, 0x00, 0x20, 0x08, 0x06, 0x70, 0x10,
0x06, 0x45, 0x60, 0x8d, 0x26, 0x04, 0xc0, 0x86, 0x0c, 0x0a, 0x86, 0x51, 0x40, 0x18, 0x63, 0x08, 0x81, 0x66, 0x01, 0x01, 0x9f, 0x0d, 0x21, 0x1c, 0x8e, 0xe3, 0x86, 0x0d, 0x88, 0x40, 0x18, 0x80,
0x11, 0x83, 0x03, 0x00, 0x41, 0x30, 0x80, 0x03, 0x34, 0x60, 0x92, 0x6e, 0x34, 0x21, 0x00, 0xe8, 0x20, 0x8c, 0x31, 0x84, 0x60, 0x0c, 0x2c, 0x18, 0xe0, 0xb3, 0x21, 0x04, 0x25, 0x06, 0x62, 0x50,
0x06, 0xc3, 0x06, 0x44, 0x20, 0x0c, 0x00, 0x86, 0x03, 0x01, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xc6, 0x72, 0x00, 0xd3, 0x14, 0x21, 0x81, 0x64, 0x2b, 0xc7, 0x03, 0x60, 0x8b, 0x03, 0x0c, 0x00,
0x00, 0x00, 0x00, 0x00, 0x61, 0x20, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x13, 0x04, 0x41, 0x2c, 0x10, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x28, 0x5b, 0x01, 0x1a, 0x8c, 0x11, 0x80,
0x20, 0x08, 0xe2, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x1b, 0x32, 0x10, 0x92, 0x44, 0x01, 0x61, 0x8c, 0x21, 0x04, 0x94, 0x05, 0x04, 0x7c, 0x36, 0x84, 0x40, 0x2c, 0xcb, 0x1a, 0x36, 0x20, 0x02, 0x61,
0x00, 0x46, 0x0c, 0x0a, 0x00, 0x04, 0xc1, 0xc0, 0x43, 0x83, 0x43, 0xc3, 0x81, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xc6, 0x72, 0x00, 0xd3, 0x14, 0x21, 0x81, 0x64, 0x2b, 0xc7, 0x03, 0x60,
0x8b, 0x03, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x61, 0x20, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x13, 0x04, 0x41, 0x2c, 0x10, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x28, 0x5b, 0x01,
0x00, 0x00, 0x00, 0x00, 0x1b, 0x33, 0x08, 0x51, 0x44, 0xc1, 0x60, 0x6c, 0xc8, 0x50, 0x4c, 0x13, 0x05, 0x84, 0x31, 0x86, 0x10, 0x60, 0x16, 0x10, 0xf0, 0xd9, 0x10, 0x22, 0xb9, 0x2e, 0x6d, 0xd8,
0x80, 0x08, 0x84, 0x01, 0x18, 0x31, 0x28, 0x00, 0x10, 0x04, 0x03, 0x2f, 0x0d, 0x10, 0x0d, 0x07, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xc6, 0x72, 0x00, 0xd3, 0x14, 0x21, 0x81, 0x64,
0x2b, 0xc7, 0x03, 0x60, 0x8b, 0x03, 0x0c, 0x00, 0x01, 0x31, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x5b, 0x86, 0x20, 0xc8, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x61, 0x20, 0x00, 0x00,
0x13, 0x00, 0x00, 0x00, 0x13, 0x04, 0x41, 0x2c, 0x10, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x28, 0x5e, 0x01, 0x1a, 0x8c, 0x11, 0x80, 0x20, 0x08, 0xe2, 0x1f, 0x00, 0x00, 0x00, 0x00,
0x33, 0x11, 0x18, 0xa0, 0x8d, 0xc2, 0xc6, 0x0c, 0x41, 0x14, 0x0d, 0x1b, 0x10, 0xc1, 0x30, 0x00, 0x23, 0x06, 0x88, 0x02, 0x82, 0x60, 0x10, 0x06, 0x62, 0x40, 0x0c, 0x92, 0x80, 0x01, 0x31, 0x00,
0x02, 0x00, 0x00, 0x00, 0x5b, 0x06, 0x21, 0xc8, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x61, 0x20, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x13, 0x04, 0x41, 0x2c, 0x10, 0x00, 0x00, 0x00,
0x0e, 0x00, 0x00, 0x00, 0x04, 0x28, 0x60, 0x81, 0x12, 0x15, 0x28, 0x4b, 0x81, 0xb2, 0x2b, 0x5d, 0x81, 0xc2, 0x14, 0x20, 0x61, 0x09, 0xd0, 0x68, 0x04, 0xa0, 0x0c, 0x68, 0x30, 0x46, 0x00, 0x82,
0x20, 0x88, 0xff, 0xc2, 0x18, 0x01, 0x08, 0x82, 0xa0, 0x0c, 0x06, 0x44, 0x18, 0x01, 0xa0, 0xc1, 0x18, 0x01, 0x08, 0x82, 0x20, 0xfe, 0xcd, 0x00, 0x8c, 0x00, 0x00, 0x00, 0x94, 0x07, 0x85, 0x41,
0x7b, 0x10, 0x18, 0xa4, 0x07, 0x87, 0x41, 0x78, 0xd0, 0x18, 0x33, 0x11, 0x10, 0xa0, 0x8d, 0xc2, 0x88, 0x81, 0x01, 0x80, 0x20, 0x18, 0xe4, 0x41, 0x1a, 0x50, 0xc2, 0x86, 0x0c, 0xc2, 0x18, 0x8c,
0xc1, 0xb0, 0x01, 0x11, 0x2c, 0x03, 0x30, 0x62, 0x60, 0x00, 0x20, 0x08, 0x06, 0x64, 0x30, 0x07, 0xd5, 0x33, 0x62, 0x60, 0x00, 0x20, 0x08, 0x06, 0x7b, 0xb0, 0x06, 0x17, 0x32, 0x62, 0xa0, 0x00,
0x20, 0x08, 0x06, 0x6b, 0x30, 0x07, 0x56, 0x20, 0x98, 0x01, 0x44, 0x06, 0xa3, 0x09, 0x01, 0x30, 0x9a, 0x20, 0x04, 0x23, 0x06, 0x07, 0x00, 0x82, 0x60, 0x30, 0x07, 0x73, 0x80, 0x1d, 0x69, 0x30,
0x9a, 0x10, 0x00, 0x23, 0x06, 0x06, 0x00, 0x82, 0x60, 0xd0, 0x07, 0x70, 0xd0, 0x35, 0x23, 0x06, 0xd4, 0x02, 0x82, 0x60, 0xd0, 0x06, 0x78, 0xa0, 0x05, 0xc2, 0x1b, 0xb0, 0xc1, 0x1b, 0xb0, 0x41,
0x41, 0x48, 0x10, 0x04, 0x55, 0xd4, 0x42, 0x09, 0x61, 0x8c, 0x18, 0x18, 0x00, 0x08, 0x82, 0xc1, 0x1f, 0xc4, 0xc1, 0xe7, 0x8c, 0x21, 0x08, 0x61, 0x30, 0x86, 0x30, 0x6c, 0x23, 0x06, 0x0e, 0x00,
0x82, 0x60, 0x80, 0x06, 0x7e, 0xd0, 0x0d, 0x0c, 0x1c, 0x08, 0x41, 0x55, 0x69, 0x6e, 0x80, 0x01, 0x31, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x5b, 0x86, 0x23, 0xd0, 0x85, 0x2d, 0x43, 0x14,
0xe8, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
D3D12_SHADER_BYTECODE code;
code.pShaderBytecode = rt_lib_dxil;
code.BytecodeLength = sizeof(rt_lib_dxil);
return code;
}
struct initial_vbo
{
float f32[3 * 3 * 2];
int16_t i16[3 * 3 * 2];
uint16_t f16[3 * 3 * 2];
};
struct initial_ibo
{
uint32_t u32[6];
uint16_t u16[6];
};
struct test_geometry
{
ID3D12Resource *vbo;
ID3D12Resource *zero_vbo;
ID3D12Resource *ibo;
};
static void destroy_test_geometry(struct test_geometry *geom)
{
ID3D12Resource_Release(geom->vbo);
ID3D12Resource_Release(geom->zero_vbo);
ID3D12Resource_Release(geom->ibo);
}
static void init_test_geometry(ID3D12Device *device, struct test_geometry *geom)
{
unsigned int i;
/* Emit quads with the different Tier 1.0 formats. */
{
struct initial_vbo initial_vbo_data;
float *pv = initial_vbo_data.f32;
*pv++ = -1.0f; *pv++ = +1.0f; *pv++ = 0.0f;
*pv++ = -1.0f; *pv++ = -1.0f; *pv++ = 0.0f;
*pv++ = +1.0f; *pv++ = -1.0f; *pv++ = 0.0f;
*pv++ = +1.0f; *pv++ = +1.0f; *pv++ = 0.0f;
*pv++ = -1.0f; *pv++ = +1.0f; *pv++ = 0.0f;
*pv++ = +1.0f; *pv++ = -1.0f; *pv++ = 0.0f;
for (i = 0; i < 3 * 3 * 2; i++)
{
initial_vbo_data.i16[i] = (int16_t)(0x7fff * initial_vbo_data.f32[i]);
initial_vbo_data.f16[i] = 0x3c00 | (initial_vbo_data.f32[i] < 0.0f ? 0x8000 : 0);
}
geom->vbo = create_upload_buffer(device, sizeof(initial_vbo_data), &initial_vbo_data);
geom->zero_vbo = create_default_buffer(device, sizeof(initial_vbo_data), D3D12_RESOURCE_FLAG_NONE, D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE);
}
{
static const struct initial_ibo initial_ibo_data = {
{ 0, 1, 2, 3, 2, 1 },
{ 0, 1, 2, 3, 2, 1 },
};
geom->ibo = create_upload_buffer(device, sizeof(initial_ibo_data), &initial_ibo_data);
}
}
static ID3D12Resource *create_transform_buffer(ID3D12Device *device, unsigned int count, float x_stride)
{
ID3D12Resource *transform_buffer;
float *transform;
unsigned int i;
transform = calloc(12 * count, sizeof(float));
for (i = 0; i < count; i++)
{
/* Row-major affine transform. */
transform[12 * i + 0] = 1.0f;
transform[12 * i + 5] = 1.0f;
transform[12 * i + 10] = 1.0f;
transform[12 * i + 3] = x_stride * (float)i;
}
transform_buffer = create_upload_buffer(device, 12 * count * sizeof(float), transform);
free(transform);
return transform_buffer;
}
static ID3D12Resource *create_aabb_buffer(ID3D12Device *device,
unsigned int geom_count, unsigned int aabb_per_geom, float x_stride)
{
D3D12_RAYTRACING_AABB *aabbs = calloc(geom_count * aabb_per_geom, sizeof(*aabbs));
ID3D12Resource *aabb_buffer;
D3D12_RAYTRACING_AABB *tmp;
unsigned int geom, aabb;
for (geom = 0; geom < geom_count; geom++)
{
for (aabb = 0; aabb < aabb_per_geom; aabb++)
{
/* Only the last AABB in a geom series is considered "active", as this is to test AABBStride parameter.
* The other ones are placed at a large, degenerate Z offset as to be ignored. */
tmp = &aabbs[geom * aabb_per_geom + aabb];
tmp->MinX = -0.5f + (float)geom * x_stride;
tmp->MaxX = +0.5f + (float)geom * x_stride;
tmp->MinY = -0.5f;
tmp->MaxY = +0.5f;
if (aabb + 1 == aabb_per_geom)
{
tmp->MinZ = -0.5f;
tmp->MaxZ = +0.5f;
}
else
{
tmp->MinZ = -10000.0f;
tmp->MaxZ = -9000.0f;
}
}
}
aabb_buffer = create_upload_buffer(device, geom_count * aabb_per_geom * sizeof(*aabbs), aabbs);
free(aabbs);
return aabb_buffer;
}
struct rt_acceleration_structure
{
ID3D12Resource *scratch;
ID3D12Resource *scratch_update;
ID3D12Resource *rtas;
};
static ID3D12Resource *duplicate_acceleration_structure(struct raytracing_test_context *context,
ID3D12Resource *rtas, D3D12_RAYTRACING_ACCELERATION_STRUCTURE_COPY_MODE mode)
{
ID3D12Resource *new_rtas;
new_rtas = create_default_buffer(context->context.device, ID3D12Resource_GetDesc(rtas).Width,
D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS,
D3D12_RESOURCE_STATE_RAYTRACING_ACCELERATION_STRUCTURE);
ID3D12GraphicsCommandList4_CopyRaytracingAccelerationStructure(context->list4,
ID3D12Resource_GetGPUVirtualAddress(new_rtas),
ID3D12Resource_GetGPUVirtualAddress(rtas), mode);
uav_barrier(context->context.list, new_rtas);
return new_rtas;
}
static void update_acceleration_structure(struct raytracing_test_context *context,
const D3D12_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_INPUTS *inputs,
struct rt_acceleration_structure *rtas)
{
D3D12_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_DESC build_info;
build_info.DestAccelerationStructureData = ID3D12Resource_GetGPUVirtualAddress(rtas->rtas);
/* In-place update is supported. */
build_info.SourceAccelerationStructureData = ID3D12Resource_GetGPUVirtualAddress(rtas->rtas);
build_info.Inputs = *inputs;
build_info.Inputs.Flags |= D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAG_PERFORM_UPDATE;
build_info.ScratchAccelerationStructureData = ID3D12Resource_GetGPUVirtualAddress(rtas->scratch_update);
ID3D12GraphicsCommandList4_BuildRaytracingAccelerationStructure(context->list4, &build_info, 0, NULL);
uav_barrier(context->context.list, rtas->rtas);
uav_barrier(context->context.list, rtas->scratch_update);
}
static void create_acceleration_structure(struct raytracing_test_context *context,
const D3D12_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_INPUTS *inputs,
struct rt_acceleration_structure *rtas, D3D12_GPU_VIRTUAL_ADDRESS postbuild_va)
{
D3D12_RAYTRACING_ACCELERATION_STRUCTURE_POSTBUILD_INFO_DESC postbuild_desc[3];
D3D12_RAYTRACING_ACCELERATION_STRUCTURE_PREBUILD_INFO prebuild_info;
D3D12_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_DESC build_info;
/* Guard against stubbed variant. */
prebuild_info.ScratchDataSizeInBytes = 16;
prebuild_info.ResultDataMaxSizeInBytes = 16;
prebuild_info.UpdateScratchDataSizeInBytes = 16;
ID3D12Device5_GetRaytracingAccelerationStructurePrebuildInfo(context->device5, inputs, &prebuild_info);
/* An AS in D3D12 is just a plain UAV-enabled buffer, similar with scratch buffers. */
rtas->scratch = create_default_buffer(context->context.device,
prebuild_info.ScratchDataSizeInBytes,
D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS,
D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
if (inputs->Flags & D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAG_ALLOW_UPDATE)
{
rtas->scratch_update = create_default_buffer(context->context.device,
prebuild_info.UpdateScratchDataSizeInBytes,
D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS,
D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
}
else
rtas->scratch_update = NULL;
/* Verify how the build mode behaves here. */
{
D3D12_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_INPUTS tmp_inputs = *inputs;
D3D12_RAYTRACING_ACCELERATION_STRUCTURE_PREBUILD_INFO tmp_prebuild_info;
/* We should ignore this flag when querying prebuild info.
* Deduced by: Equal sizes, no validation errors.
* Vulkan does not seem to care either, and this trips validation
* errors in neither D3D12 nor Vulkan. */
tmp_inputs.Flags |= D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAG_PERFORM_UPDATE;
ID3D12Device5_GetRaytracingAccelerationStructurePrebuildInfo(context->device5, &tmp_inputs, &tmp_prebuild_info);
ok(tmp_prebuild_info.ResultDataMaxSizeInBytes == prebuild_info.ResultDataMaxSizeInBytes,
"Size mismatch, %"PRIu64" != %"PRIu64".\n",
tmp_prebuild_info.ResultDataMaxSizeInBytes,
prebuild_info.ResultDataMaxSizeInBytes);
ok(tmp_prebuild_info.ScratchDataSizeInBytes == prebuild_info.ScratchDataSizeInBytes,
"Size mismatch, %"PRIu64" != %"PRIu64".\n",
tmp_prebuild_info.ScratchDataSizeInBytes,
prebuild_info.ScratchDataSizeInBytes);
ok(tmp_prebuild_info.UpdateScratchDataSizeInBytes == prebuild_info.UpdateScratchDataSizeInBytes,
"Size mismatch, %"PRIu64" != %"PRIu64".\n",
tmp_prebuild_info.UpdateScratchDataSizeInBytes,
prebuild_info.UpdateScratchDataSizeInBytes);
}
rtas->rtas = create_default_buffer(context->context.device,
prebuild_info.ResultDataMaxSizeInBytes,
D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS,
D3D12_RESOURCE_STATE_RAYTRACING_ACCELERATION_STRUCTURE);
build_info.DestAccelerationStructureData = ID3D12Resource_GetGPUVirtualAddress(rtas->rtas);
build_info.Inputs = *inputs;
build_info.ScratchAccelerationStructureData = ID3D12Resource_GetGPUVirtualAddress(rtas->scratch);
build_info.SourceAccelerationStructureData = 0;
postbuild_desc[0].InfoType = D3D12_RAYTRACING_ACCELERATION_STRUCTURE_POSTBUILD_INFO_COMPACTED_SIZE;
postbuild_desc[0].DestBuffer = postbuild_va;
postbuild_desc[1].InfoType = D3D12_RAYTRACING_ACCELERATION_STRUCTURE_POSTBUILD_INFO_CURRENT_SIZE;
postbuild_desc[1].DestBuffer = postbuild_desc[0].DestBuffer + sizeof(D3D12_RAYTRACING_ACCELERATION_STRUCTURE_POSTBUILD_INFO_COMPACTED_SIZE_DESC);
postbuild_desc[2].InfoType = D3D12_RAYTRACING_ACCELERATION_STRUCTURE_POSTBUILD_INFO_SERIALIZATION;
postbuild_desc[2].DestBuffer = postbuild_desc[1].DestBuffer + sizeof(D3D12_RAYTRACING_ACCELERATION_STRUCTURE_POSTBUILD_INFO_CURRENT_SIZE_DESC);
ID3D12GraphicsCommandList4_BuildRaytracingAccelerationStructure(context->list4, &build_info,
postbuild_va ? ARRAY_SIZE(postbuild_desc) : 0, postbuild_desc);
uav_barrier(context->context.list, rtas->rtas);
uav_barrier(context->context.list, rtas->scratch);
}
static void destroy_acceleration_structure(struct rt_acceleration_structure *rtas)
{
ID3D12Resource_Release(rtas->scratch);
ID3D12Resource_Release(rtas->rtas);
if (rtas->scratch_update)
ID3D12Resource_Release(rtas->scratch_update);
}
struct test_rt_geometry
{
ID3D12Resource *bottom_acceleration_structures_tri[3];
ID3D12Resource *bottom_acceleration_structures_aabb[3];
ID3D12Resource *top_acceleration_structures[3];
struct rt_acceleration_structure bottom_rtas_tri;
struct rt_acceleration_structure bottom_rtas_aabb;
struct rt_acceleration_structure top_rtas;
ID3D12Resource *transform_buffer;
ID3D12Resource *aabb_buffer;
ID3D12Resource *instance_buffer;
};
static void destroy_rt_geometry(struct test_rt_geometry *rt_geom)
{
unsigned int i;
for (i = 0; i < ARRAY_SIZE(rt_geom->bottom_acceleration_structures_tri); i++)
ID3D12Resource_Release(rt_geom->bottom_acceleration_structures_tri[i]);
for (i = 0; i < ARRAY_SIZE(rt_geom->bottom_acceleration_structures_aabb); i++)
ID3D12Resource_Release(rt_geom->bottom_acceleration_structures_aabb[i]);
for (i = 0; i < ARRAY_SIZE(rt_geom->top_acceleration_structures); i++)
ID3D12Resource_Release(rt_geom->top_acceleration_structures[i]);
ID3D12Resource_Release(rt_geom->transform_buffer);
ID3D12Resource_Release(rt_geom->aabb_buffer);
ID3D12Resource_Release(rt_geom->instance_buffer);
destroy_acceleration_structure(&rt_geom->bottom_rtas_tri);
destroy_acceleration_structure(&rt_geom->bottom_rtas_aabb);
destroy_acceleration_structure(&rt_geom->top_rtas);
}
static bool instance_index_is_aabb(unsigned int index)
{
return !!(index & 2);
}
static void init_rt_geometry(struct raytracing_test_context *context, struct test_rt_geometry *rt_geom,
struct test_geometry *geom,
unsigned int num_geom_desc, float geom_offset_x,
unsigned int num_unmasked_instances_y, float instance_geom_scale, float instance_offset_y,
D3D12_GPU_VIRTUAL_ADDRESS postbuild_va)
{
#define NUM_GEOM_TEMPLATES 6
#define NUM_AABB_PER_GEOM 2
D3D12_RAYTRACING_GEOMETRY_DESC geom_desc_template[NUM_GEOM_TEMPLATES];
D3D12_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_INPUTS inputs;
D3D12_RAYTRACING_INSTANCE_DESC *instance_desc;
D3D12_RAYTRACING_GEOMETRY_DESC *geom_desc;
unsigned int i;
/* Create X * Y quads where X = num_geom_desc, and Y = num_unmasked_instances_y.
* Additionally, create a set of quads at Y iteration -1 which are intended to be masked
* (miss shader should be triggered).
* The intention is that hit SBT index is row-linear, i.e. hit index = Y * num_geom_desc + X.
* Size and placement of the quads are controlled by parameters. */
rt_geom->transform_buffer = create_transform_buffer(context->context.device, num_geom_desc, geom_offset_x);
rt_geom->aabb_buffer = create_aabb_buffer(context->context.device, num_geom_desc, NUM_AABB_PER_GEOM, geom_offset_x);
memset(geom_desc_template, 0, sizeof(geom_desc_template));
/* Setup a template for different geom descs which all effectively do the same thing, a simple quad. */
/* Tests the configuration space of the 6 supported vertex formats, and the 3 index types. */
geom_desc_template[0].Type = D3D12_RAYTRACING_GEOMETRY_TYPE_TRIANGLES;
geom_desc_template[0].Triangles.VertexBuffer.StartAddress =
ID3D12Resource_GetGPUVirtualAddress(geom->vbo) + offsetof(struct initial_vbo, f32);
geom_desc_template[0].Triangles.VertexBuffer.StrideInBytes = 3 * sizeof(float);
geom_desc_template[0].Triangles.VertexFormat = DXGI_FORMAT_R32G32B32_FLOAT;
geom_desc_template[0].Triangles.VertexCount = 6;
geom_desc_template[1] = geom_desc_template[0];
/* First, render something wrong, update the RTAS later and verify that it works. */
geom_desc_template[1].Triangles.VertexBuffer.StartAddress =
ID3D12Resource_GetGPUVirtualAddress(geom->zero_vbo) + offsetof(struct initial_vbo, f32);
geom_desc_template[1].Triangles.VertexFormat = DXGI_FORMAT_R32G32_FLOAT;
geom_desc_template[2].Type = D3D12_RAYTRACING_GEOMETRY_TYPE_TRIANGLES;
geom_desc_template[2].Triangles.VertexBuffer.StartAddress =
ID3D12Resource_GetGPUVirtualAddress(geom->vbo) + offsetof(struct initial_vbo, i16);
geom_desc_template[2].Triangles.VertexBuffer.StrideInBytes = 3 * sizeof(int16_t);
geom_desc_template[2].Triangles.VertexFormat = DXGI_FORMAT_R16G16B16A16_SNORM;
geom_desc_template[2].Triangles.VertexCount = 4;
geom_desc_template[2].Triangles.IndexBuffer =
ID3D12Resource_GetGPUVirtualAddress(geom->ibo) + offsetof(struct initial_ibo, u16);
geom_desc_template[2].Triangles.IndexFormat = DXGI_FORMAT_R16_UINT;
geom_desc_template[2].Triangles.IndexCount = 6;
geom_desc_template[3] = geom_desc_template[2];
geom_desc_template[3].Triangles.VertexFormat = DXGI_FORMAT_R16G16_SNORM;
geom_desc_template[3].Triangles.IndexBuffer =
ID3D12Resource_GetGPUVirtualAddress(geom->ibo) + offsetof(struct initial_ibo, u32);
geom_desc_template[3].Triangles.IndexFormat = DXGI_FORMAT_R32_UINT;
geom_desc_template[4] = geom_desc_template[2];
geom_desc_template[4].Triangles.VertexBuffer.StartAddress =
ID3D12Resource_GetGPUVirtualAddress(geom->vbo) + offsetof(struct initial_vbo, f16);
geom_desc_template[4].Triangles.VertexFormat = DXGI_FORMAT_R16G16B16A16_FLOAT;
geom_desc_template[5] = geom_desc_template[3];
geom_desc_template[5].Triangles.VertexBuffer.StartAddress =
ID3D12Resource_GetGPUVirtualAddress(geom->vbo) + offsetof(struct initial_vbo, f16);
geom_desc_template[5].Triangles.VertexFormat = DXGI_FORMAT_R16G16_FLOAT;
/* Every other geometry desc is considered opaque.
* Lets us test any-hit invocation rules. */
for (i = 0; i < ARRAY_SIZE(geom_desc_template); i++)
{
geom_desc_template[i].Flags = (i & 1) ? D3D12_RAYTRACING_GEOMETRY_FLAG_OPAQUE : D3D12_RAYTRACING_GEOMETRY_FLAG_NONE;
geom_desc_template[i].Flags |= D3D12_RAYTRACING_GEOMETRY_FLAG_NO_DUPLICATE_ANYHIT_INVOCATION;
}
/* Create bottom AS. One quad is centered around origin, but other triangles are translated. */
memset(&inputs, 0, sizeof(inputs));
inputs.DescsLayout = D3D12_ELEMENTS_LAYOUT_ARRAY;
inputs.NumDescs = num_geom_desc;
inputs.Type = D3D12_RAYTRACING_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL;
inputs.Flags = D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAG_PREFER_FAST_TRACE |
D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAG_ALLOW_COMPACTION |
D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAG_ALLOW_UPDATE;
geom_desc = malloc(sizeof(*geom_desc) * num_geom_desc);
for (i = 0; i < num_geom_desc; i++)
geom_desc[i] = geom_desc_template[i % ARRAY_SIZE(geom_desc_template)];
inputs.pGeometryDescs = geom_desc;
/* Identity transform for index 0, checks that we handle NULL here for geom_desc 0. */
for (i = 1; i < num_geom_desc; i++)
{
geom_desc[i].Triangles.Transform3x4 =
ID3D12Resource_GetGPUVirtualAddress(rt_geom->transform_buffer) + i * 4 * 3 * sizeof(float);
}
create_acceleration_structure(context, &inputs, &rt_geom->bottom_rtas_tri, postbuild_va);
/* Update, and now use correct VBO. */
geom_desc_template[1].Triangles.VertexBuffer.StartAddress =
ID3D12Resource_GetGPUVirtualAddress(geom->vbo) + offsetof(struct initial_vbo, f32);
for (i = 1; i < num_geom_desc; i += ARRAY_SIZE(geom_desc_template))
geom_desc[i].Triangles.VertexBuffer = geom_desc_template[1].Triangles.VertexBuffer;
update_acceleration_structure(context, &inputs, &rt_geom->bottom_rtas_tri);
for (i = 0; i < num_geom_desc; i++)
{
geom_desc[i].Type = D3D12_RAYTRACING_GEOMETRY_TYPE_PROCEDURAL_PRIMITIVE_AABBS;
geom_desc[i].AABBs.AABBCount = NUM_AABB_PER_GEOM;
geom_desc[i].AABBs.AABBs.StartAddress = ID3D12Resource_GetGPUVirtualAddress(rt_geom->aabb_buffer) +
i * geom_desc[i].AABBs.AABBCount * sizeof(D3D12_RAYTRACING_AABB);
geom_desc[i].AABBs.AABBs.StrideInBytes = sizeof(D3D12_RAYTRACING_AABB);
}
create_acceleration_structure(context, &inputs, &rt_geom->bottom_rtas_aabb, 0);
/* Tests CLONE and COMPACTING copies. COMPACTING can never increase size, so it's safe to allocate up front.
* We test the compacted size later. */
rt_geom->bottom_acceleration_structures_tri[0] = rt_geom->bottom_rtas_tri.rtas;
ID3D12Resource_AddRef(rt_geom->bottom_rtas_tri.rtas);
rt_geom->bottom_acceleration_structures_tri[1] = duplicate_acceleration_structure(context,
rt_geom->bottom_acceleration_structures_tri[0],
D3D12_RAYTRACING_ACCELERATION_STRUCTURE_COPY_MODE_COMPACT);
rt_geom->bottom_acceleration_structures_tri[2] = duplicate_acceleration_structure(context,
rt_geom->bottom_acceleration_structures_tri[1],
D3D12_RAYTRACING_ACCELERATION_STRUCTURE_COPY_MODE_CLONE);
rt_geom->bottom_acceleration_structures_aabb[0] = rt_geom->bottom_rtas_aabb.rtas;
ID3D12Resource_AddRef(rt_geom->bottom_rtas_aabb.rtas);
rt_geom->bottom_acceleration_structures_aabb[1] = duplicate_acceleration_structure(context,
rt_geom->bottom_acceleration_structures_aabb[0],
D3D12_RAYTRACING_ACCELERATION_STRUCTURE_COPY_MODE_COMPACT);
rt_geom->bottom_acceleration_structures_aabb[2] = duplicate_acceleration_structure(context,
rt_geom->bottom_acceleration_structures_aabb[1],
D3D12_RAYTRACING_ACCELERATION_STRUCTURE_COPY_MODE_CLONE);
/* Create instance buffer. One for every top-level entry into the AS. */
instance_desc = calloc(num_unmasked_instances_y + 1, sizeof(*instance_desc));
for (i = 0; i < num_unmasked_instances_y; i++)
{
instance_desc[i].Transform[0][0] = instance_geom_scale;
instance_desc[i].Transform[1][1] = instance_geom_scale;
instance_desc[i].Transform[2][2] = instance_geom_scale;
instance_desc[i].Transform[1][3] = instance_offset_y * (float)i;
instance_desc[i].InstanceMask = 0xff;
instance_desc[i].InstanceContributionToHitGroupIndex = num_geom_desc * i;
if (i == 0 || i == 2)
instance_desc[i].Flags = D3D12_RAYTRACING_INSTANCE_FLAG_FORCE_OPAQUE;
else if (i == 1 || i == 3)
instance_desc[i].Flags = D3D12_RAYTRACING_INSTANCE_FLAG_FORCE_NON_OPAQUE;
if (instance_index_is_aabb(i))
{
instance_desc[i].AccelerationStructure =
ID3D12Resource_GetGPUVirtualAddress(rt_geom->bottom_acceleration_structures_aabb[i & 1]);
}
else
{
instance_desc[i].AccelerationStructure =
ID3D12Resource_GetGPUVirtualAddress(rt_geom->bottom_acceleration_structures_tri[i & 1]);
}
}
instance_desc[num_unmasked_instances_y].Transform[0][0] = instance_geom_scale;
instance_desc[num_unmasked_instances_y].Transform[1][1] = instance_geom_scale;
instance_desc[num_unmasked_instances_y].Transform[2][2] = instance_geom_scale;
instance_desc[num_unmasked_instances_y].Transform[1][3] = -instance_offset_y;
instance_desc[num_unmasked_instances_y].InstanceMask = 0xfe; /* This instance will be masked out since shader uses mask of 0x01. */
instance_desc[num_unmasked_instances_y].InstanceContributionToHitGroupIndex = 0;
instance_desc[num_unmasked_instances_y].AccelerationStructure =
ID3D12Resource_GetGPUVirtualAddress(rt_geom->bottom_acceleration_structures_tri[2]);
rt_geom->instance_buffer = create_upload_buffer(context->context.device,
(num_unmasked_instances_y + 1) * sizeof(*instance_desc), instance_desc);
/* Create top AS */
memset(&inputs, 0, sizeof(inputs));
inputs.DescsLayout = D3D12_ELEMENTS_LAYOUT_ARRAY;
inputs.NumDescs = num_unmasked_instances_y + 1;
inputs.InstanceDescs = ID3D12Resource_GetGPUVirtualAddress(rt_geom->instance_buffer);
inputs.Type = D3D12_RAYTRACING_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL;
inputs.Flags = D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAG_PREFER_FAST_TRACE |
D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAG_ALLOW_COMPACTION;
create_acceleration_structure(context, &inputs, &rt_geom->top_rtas,
postbuild_va ? (postbuild_va + 4 * sizeof(uint64_t)) : 0);
/* Tests CLONE and COMPACTING copies. COMPACTING can never increase size, so it's safe to allocate up front.
* We test the compacted size later. */
rt_geom->top_acceleration_structures[0] = rt_geom->top_rtas.rtas;
ID3D12Resource_AddRef(rt_geom->top_rtas.rtas);
rt_geom->top_acceleration_structures[1] = duplicate_acceleration_structure(context,
rt_geom->top_acceleration_structures[0], D3D12_RAYTRACING_ACCELERATION_STRUCTURE_COPY_MODE_COMPACT);
rt_geom->top_acceleration_structures[2] = duplicate_acceleration_structure(context,
rt_geom->top_acceleration_structures[1], D3D12_RAYTRACING_ACCELERATION_STRUCTURE_COPY_MODE_CLONE);
free(geom_desc);
free(instance_desc);
}
struct rt_pso_factory
{
D3D12_STATE_SUBOBJECT *subobjects;
size_t subobjects_count;
void **allocs;
size_t allocs_count;
};
static void rt_pso_factory_init(struct rt_pso_factory *factory)
{
memset(factory, 0, sizeof(*factory));
}
static unsigned int rt_pso_factory_add_subobject(struct rt_pso_factory *factory, const D3D12_STATE_SUBOBJECT *object)
{
unsigned ret = factory->subobjects_count;
factory->subobjects = realloc(factory->subobjects, (factory->subobjects_count + 1) * sizeof(*factory->subobjects));
factory->subobjects[factory->subobjects_count++] = *object;
return ret;
}
static void *rt_pso_factory_calloc(struct rt_pso_factory *factory, size_t nmemb, size_t count)
{
void *mem = calloc(nmemb, count);
factory->allocs = realloc(factory->allocs, (factory->allocs_count + 1) * sizeof(*factory->allocs));
factory->allocs[factory->allocs_count++] = mem;
return mem;
}
static unsigned int rt_pso_factory_add_state_object_config(struct rt_pso_factory *factory, D3D12_STATE_OBJECT_FLAGS flags)
{
D3D12_STATE_OBJECT_CONFIG *config;
D3D12_STATE_SUBOBJECT desc;
config = rt_pso_factory_calloc(factory, 1, sizeof(*config));
config->Flags = flags;
desc.Type = D3D12_STATE_SUBOBJECT_TYPE_STATE_OBJECT_CONFIG;
desc.pDesc = config;
return rt_pso_factory_add_subobject(factory, &desc);
}
static unsigned int rt_pso_factory_add_pipeline_config(struct rt_pso_factory *factory, unsigned int recursion_depth)
{
D3D12_RAYTRACING_PIPELINE_CONFIG *config;
D3D12_STATE_SUBOBJECT desc;
config = rt_pso_factory_calloc(factory, 1, sizeof(*config));
config->MaxTraceRecursionDepth = recursion_depth;
desc.Type = D3D12_STATE_SUBOBJECT_TYPE_RAYTRACING_PIPELINE_CONFIG;
desc.pDesc = config;
return rt_pso_factory_add_subobject(factory, &desc);
}
static unsigned int rt_pso_factory_add_pipeline_config1(struct rt_pso_factory *factory, unsigned int recursion_depth,
D3D12_RAYTRACING_PIPELINE_FLAGS flags)
{
D3D12_RAYTRACING_PIPELINE_CONFIG1 *config;
D3D12_STATE_SUBOBJECT desc;
config = rt_pso_factory_calloc(factory, 1, sizeof(*config));
config->MaxTraceRecursionDepth = recursion_depth;
config->Flags = flags;
desc.Type = D3D12_STATE_SUBOBJECT_TYPE_RAYTRACING_PIPELINE_CONFIG1;
desc.pDesc = config;
return rt_pso_factory_add_subobject(factory, &desc);
}
static unsigned int rt_pso_factory_add_shader_config(struct rt_pso_factory *factory,
unsigned int attrib_size, unsigned int payload_size)
{
D3D12_RAYTRACING_SHADER_CONFIG *config;
D3D12_STATE_SUBOBJECT desc;
config = rt_pso_factory_calloc(factory, 1, sizeof(*config));
config->MaxAttributeSizeInBytes = attrib_size;
config->MaxPayloadSizeInBytes = payload_size;
desc.Type = D3D12_STATE_SUBOBJECT_TYPE_RAYTRACING_SHADER_CONFIG;
desc.pDesc = config;
return rt_pso_factory_add_subobject(factory, &desc);
}
static unsigned int rt_pso_factory_add_global_root_signature(struct rt_pso_factory *factory, ID3D12RootSignature *rs)
{
D3D12_GLOBAL_ROOT_SIGNATURE *global_rs_desc;
D3D12_STATE_SUBOBJECT desc;
global_rs_desc = rt_pso_factory_calloc(factory, 1, sizeof(*global_rs_desc));
global_rs_desc->pGlobalRootSignature = rs;
desc.Type = D3D12_STATE_SUBOBJECT_TYPE_GLOBAL_ROOT_SIGNATURE;
desc.pDesc = global_rs_desc;
return rt_pso_factory_add_subobject(factory, &desc);
}
static unsigned int rt_pso_factory_add_local_root_signature(struct rt_pso_factory *factory, ID3D12RootSignature *rs)
{
D3D12_LOCAL_ROOT_SIGNATURE *local_rs_desc;
D3D12_STATE_SUBOBJECT desc;
local_rs_desc = rt_pso_factory_calloc(factory, 1, sizeof(*local_rs_desc));
local_rs_desc->pLocalRootSignature = rs;
desc.Type = D3D12_STATE_SUBOBJECT_TYPE_LOCAL_ROOT_SIGNATURE;
desc.pDesc = local_rs_desc;
return rt_pso_factory_add_subobject(factory, &desc);
}
static unsigned int rt_pso_factory_add_dxil_library(struct rt_pso_factory *factory,
D3D12_SHADER_BYTECODE dxil, unsigned int num_exports, D3D12_EXPORT_DESC *exports)
{
D3D12_DXIL_LIBRARY_DESC *lib;
D3D12_STATE_SUBOBJECT desc;
lib = rt_pso_factory_calloc(factory, 1, sizeof(*lib));
lib->DXILLibrary = dxil;
lib->NumExports = num_exports;
lib->pExports = exports;
desc.Type = D3D12_STATE_SUBOBJECT_TYPE_DXIL_LIBRARY;
desc.pDesc = lib;
return rt_pso_factory_add_subobject(factory, &desc);
}
static unsigned int rt_pso_factory_add_hit_group(struct rt_pso_factory *factory, const D3D12_HIT_GROUP_DESC *hit_group)
{
D3D12_STATE_SUBOBJECT desc;
desc.Type = D3D12_STATE_SUBOBJECT_TYPE_HIT_GROUP;
desc.pDesc = hit_group;
return rt_pso_factory_add_subobject(factory, &desc);
}
static unsigned int rt_pso_factory_add_subobject_to_exports_association(struct rt_pso_factory *factory,
unsigned int subobject_index, unsigned int num_exports, LPCWSTR *exports)
{
D3D12_SUBOBJECT_TO_EXPORTS_ASSOCIATION *assoc;
D3D12_STATE_SUBOBJECT desc;
assoc = rt_pso_factory_calloc(factory, 1, sizeof(*assoc));
assoc->pExports = exports;
assoc->NumExports = num_exports;
/* Resolve later when compiling since base pointer can change. Encode offset here for now. */
assoc->pSubobjectToAssociate = (const void*)(uintptr_t)subobject_index;
desc.Type = D3D12_STATE_SUBOBJECT_TYPE_SUBOBJECT_TO_EXPORTS_ASSOCIATION;
desc.pDesc = assoc;
return rt_pso_factory_add_subobject(factory, &desc);
}
static unsigned int rt_pso_factory_add_existing_collection(struct rt_pso_factory *factory,
ID3D12StateObject *collection, unsigned int num_exports, D3D12_EXPORT_DESC *exports)
{
D3D12_EXISTING_COLLECTION_DESC *coll;
D3D12_STATE_SUBOBJECT desc;
coll = rt_pso_factory_calloc(factory, 1, sizeof(*coll));
coll->NumExports = num_exports;
coll->pExports = exports;
coll->pExistingCollection = collection;
desc.Type = D3D12_STATE_SUBOBJECT_TYPE_EXISTING_COLLECTION;
desc.pDesc = coll;
return rt_pso_factory_add_subobject(factory, &desc);
}
static unsigned int rt_pso_factory_add_default_node_mask(struct rt_pso_factory* factory)
{
D3D12_STATE_SUBOBJECT desc;
D3D12_NODE_MASK *mask;
mask = rt_pso_factory_calloc(factory, 1, sizeof(*mask));
/* This node mask is weird and some runtimes have bugs. We'll just ignore it anyways in vkd3d-proton.
* https://docs.microsoft.com/en-us/windows/win32/api/d3d12/ne-d3d12-d3d12_state_subobject_type */
mask->NodeMask = 1;
desc.Type = D3D12_STATE_SUBOBJECT_TYPE_NODE_MASK;
desc.pDesc = mask;
return rt_pso_factory_add_subobject(factory, &desc);
}
static ID3D12StateObject *rt_pso_factory_compile(struct raytracing_test_context *context,
struct rt_pso_factory *factory,
D3D12_STATE_OBJECT_TYPE type)
{
D3D12_SUBOBJECT_TO_EXPORTS_ASSOCIATION *assoc;
D3D12_STATE_OBJECT_DESC desc;
ID3D12StateObject *rt_pso;
HRESULT hr;
size_t i;
memset(&desc, 0, sizeof(desc));
desc.Type = type;
desc.NumSubobjects = factory->subobjects_count;
desc.pSubobjects = factory->subobjects;
for (i = 0; i < factory->subobjects_count; i++)
{
if (factory->subobjects[i].Type == D3D12_STATE_SUBOBJECT_TYPE_SUBOBJECT_TO_EXPORTS_ASSOCIATION)
{
/* Resolve offsets to true pointers. */
assoc = (D3D12_SUBOBJECT_TO_EXPORTS_ASSOCIATION *)factory->subobjects[i].pDesc;
assoc->pSubobjectToAssociate = factory->subobjects + (uintptr_t)assoc->pSubobjectToAssociate;
}
}
rt_pso = NULL;
hr = ID3D12Device5_CreateStateObject(context->device5, &desc, &IID_ID3D12StateObject, (void **)&rt_pso);
ok(SUCCEEDED(hr), "Failed to create RT PSO, hr %#x.\n", hr);
free(factory->subobjects);
for (i = 0; i < factory->allocs_count; i++)
free(factory->allocs[i]);
free(factory->allocs);
memset(factory, 0, sizeof(*factory));
return rt_pso;
}
static ID3D12StateObject *rt_pso_add_to_state_object(ID3D12Device5 *device, ID3D12StateObject *parent, ID3D12StateObject *addition,
const D3D12_HIT_GROUP_DESC *hit_group)
{
D3D12_EXISTING_COLLECTION_DESC existing;
ID3D12StateObject *new_state_object;
D3D12_STATE_OBJECT_CONFIG config;
D3D12_STATE_SUBOBJECT subobj[3];
D3D12_STATE_OBJECT_DESC desc;
ID3D12Device7 *device7;
HRESULT hr;
desc.NumSubobjects = 1;
desc.Type = D3D12_STATE_OBJECT_TYPE_RAYTRACING_PIPELINE;
desc.pSubobjects = subobj;
subobj[0].Type = D3D12_STATE_SUBOBJECT_TYPE_EXISTING_COLLECTION;
subobj[0].pDesc = &existing;
existing.NumExports = 0;
existing.pExports = NULL;
existing.pExistingCollection = addition;
if (hit_group)
{
subobj[desc.NumSubobjects].Type = D3D12_STATE_SUBOBJECT_TYPE_HIT_GROUP;
subobj[desc.NumSubobjects].pDesc = hit_group;
desc.NumSubobjects++;
}
if (FAILED(ID3D12Device5_QueryInterface(device, &IID_ID3D12Device7, (void**)&device7)))
{
skip("Failed to query ID3D12Device7.\n");
return NULL;
}
/* Have to add ALLOW_STATE_OBJECT_ADDITIONS for both parent and addition. */
hr = ID3D12Device7_AddToStateObject(device7, &desc, parent, &IID_ID3D12StateObject, (void**)&new_state_object);
ok(hr == E_INVALIDARG, "Unexpected hr #%x.\n", hr);
config.Flags = D3D12_STATE_OBJECT_FLAG_ALLOW_STATE_OBJECT_ADDITIONS;
subobj[desc.NumSubobjects].Type = D3D12_STATE_SUBOBJECT_TYPE_STATE_OBJECT_CONFIG;
subobj[desc.NumSubobjects].pDesc = &config;
desc.NumSubobjects++;
/* Type must be RAYTRACING_PIPELINE. */
desc.Type = D3D12_STATE_OBJECT_TYPE_COLLECTION;
hr = ID3D12Device7_AddToStateObject(device7, &desc, parent, &IID_ID3D12StateObject, (void**)&new_state_object);
ok(hr == E_INVALIDARG, "Unexpected hr #%x.\n", hr);
desc.Type = D3D12_STATE_OBJECT_TYPE_RAYTRACING_PIPELINE;
hr = ID3D12Device7_AddToStateObject(device7, &desc, parent, &IID_ID3D12StateObject, (void**)&new_state_object);
ok(SUCCEEDED(hr), "Failed to AddToStateObject, hr #%x.\n", hr);
if (FAILED(hr))
new_state_object = NULL;
ID3D12Device7_Release(device7);
return new_state_object;
}
enum rt_test_mode
{
TEST_MODE_PLAIN,
TEST_MODE_TRACE_RAY_FORCE_OPAQUE,
TEST_MODE_TRACE_RAY_FORCE_NON_OPAQUE,
TEST_MODE_TRACE_RAY_SKIP_TRIANGLES,
TEST_MODE_TRACE_RAY_SKIP_AABBS,
TEST_MODE_PSO_SKIP_TRIANGLES,
TEST_MODE_PSO_SKIP_AABBS,
TEST_MODE_PSO_ADD_TO_STATE_OBJECT,
};
static ID3D12StateObject *create_rt_collection(struct raytracing_test_context *context,
unsigned int num_exports, D3D12_EXPORT_DESC *exports,
const D3D12_HIT_GROUP_DESC *hit_group,
ID3D12RootSignature *global_rs, ID3D12RootSignature *local_rs,
enum rt_test_mode test_mode)
{
struct rt_pso_factory factory;
rt_pso_factory_init(&factory);
rt_pso_factory_add_default_node_mask(&factory);
if (test_mode == TEST_MODE_PSO_ADD_TO_STATE_OBJECT)
{
rt_pso_factory_add_state_object_config(&factory,
D3D12_STATE_OBJECT_FLAG_ALLOW_STATE_OBJECT_ADDITIONS |
D3D12_STATE_OBJECT_FLAG_ALLOW_EXTERNAL_DEPENDENCIES_ON_LOCAL_DEFINITIONS);
}
else
{
rt_pso_factory_add_state_object_config(&factory,
D3D12_STATE_OBJECT_FLAG_ALLOW_EXTERNAL_DEPENDENCIES_ON_LOCAL_DEFINITIONS);
}
if (test_mode == TEST_MODE_PSO_SKIP_TRIANGLES)
rt_pso_factory_add_pipeline_config1(&factory, 1, D3D12_RAYTRACING_PIPELINE_FLAG_SKIP_TRIANGLES);
else if (test_mode == TEST_MODE_PSO_SKIP_AABBS)
rt_pso_factory_add_pipeline_config1(&factory, 1, D3D12_RAYTRACING_PIPELINE_FLAG_SKIP_PROCEDURAL_PRIMITIVES);
else
rt_pso_factory_add_pipeline_config(&factory, 1);
rt_pso_factory_add_shader_config(&factory, 8, 8);
if (global_rs)
rt_pso_factory_add_global_root_signature(&factory, global_rs);
rt_pso_factory_add_dxil_library(&factory, get_default_rt_lib(), num_exports, exports);
if (local_rs)
rt_pso_factory_add_local_root_signature(&factory, local_rs);
if (hit_group)
rt_pso_factory_add_hit_group(&factory, hit_group);
return rt_pso_factory_compile(context, &factory, D3D12_STATE_OBJECT_TYPE_COLLECTION);
}
static uint32_t test_mode_to_trace_flags(enum rt_test_mode mode)
{
switch (mode)
{
default:
case TEST_MODE_PLAIN:
return 0;
case TEST_MODE_TRACE_RAY_FORCE_OPAQUE:
return D3D12_RAY_FLAG_FORCE_OPAQUE;
case TEST_MODE_TRACE_RAY_FORCE_NON_OPAQUE:
return D3D12_RAY_FLAG_FORCE_NON_OPAQUE;
case TEST_MODE_TRACE_RAY_SKIP_TRIANGLES:
return D3D12_RAY_FLAG_SKIP_TRIANGLES;
case TEST_MODE_TRACE_RAY_SKIP_AABBS:
return D3D12_RAY_FLAG_SKIP_PROCEDURAL_PRIMITIVES;
}
}
static void test_raytracing_pipeline(enum rt_test_mode mode, D3D12_RAYTRACING_TIER minimum_tier)
{
#define NUM_GEOM_DESC 6
#define NUM_UNMASKED_INSTANCES 8
#define INSTANCE_OFFSET_Y (100.0f)
#define GEOM_OFFSET_X (10.0f)
#define INSTANCE_GEOM_SCALE (0.5f)
D3D12_RAYTRACING_ACCELERATION_STRUCTURE_POSTBUILD_INFO_DESC postbuild_desc[3];
float sbt_colors[NUM_GEOM_DESC * NUM_UNMASKED_INSTANCES + 1][2];
D3D12_ROOT_SIGNATURE_DESC root_signature_desc;
D3D12_DESCRIPTOR_RANGE descriptor_ranges[2];
ID3D12GraphicsCommandList4 *command_list4;
ID3D12StateObject *rt_object_library_aabb;
ID3D12StateObject *rt_object_library_tri;
D3D12_ROOT_PARAMETER root_parameters[2];
ID3D12GraphicsCommandList *command_list;
D3D12_CPU_DESCRIPTOR_HANDLE cpu_handle;
D3D12_GPU_DESCRIPTOR_HANDLE gpu_handle;
struct raytracing_test_context context;
ID3D12DescriptorHeap *descriptor_heap;
ID3D12RootSignature *local_rs_table;
struct test_rt_geometry test_rtases;
D3D12_DESCRIPTOR_RANGE table_range;
ID3D12Resource *postbuild_readback;
ID3D12Resource *sbt_colors_buffer;
ID3D12Resource *postbuild_buffer;
unsigned int i, descriptor_size;
ID3D12StateObject *rt_pso_added;
ID3D12RootSignature *global_rs;
struct test_geometry test_geom;
ID3D12RootSignature *local_rs;
ID3D12Resource *ray_positions;
struct resource_readback rb;
unsigned int instance, geom;
ID3D12Resource *ray_colors;
ID3D12CommandQueue *queue;
ID3D12StateObject *rt_pso;
unsigned int ref_count;
ID3D12Device *device;
ID3D12Resource *sbt;
HRESULT hr;
if (!init_raytracing_test_context(&context, minimum_tier))
return;
device = context.context.device;
command_list = context.context.list;
command_list4 = context.list4;
queue = context.context.queue;
postbuild_readback = create_readback_buffer(device, 4096);
postbuild_buffer = create_default_buffer(device, 4096, D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
init_test_geometry(device, &test_geom);
init_rt_geometry(&context, &test_rtases, &test_geom,
NUM_GEOM_DESC, GEOM_OFFSET_X,
NUM_UNMASKED_INSTANCES, INSTANCE_GEOM_SCALE, INSTANCE_OFFSET_Y,
ID3D12Resource_GetGPUVirtualAddress(postbuild_buffer));
/* Create global root signature. All RT shaders can access these parameters. */
{
memset(&root_signature_desc, 0, sizeof(root_signature_desc));
memset(root_parameters, 0, sizeof(root_parameters));
memset(descriptor_ranges, 0, sizeof(descriptor_ranges));
root_signature_desc.NumParameters = 2;
root_signature_desc.pParameters = root_parameters;
root_parameters[0].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
root_parameters[0].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
root_parameters[0].DescriptorTable.NumDescriptorRanges = 2;
root_parameters[0].DescriptorTable.pDescriptorRanges = descriptor_ranges;
descriptor_ranges[0].RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV; /* Acceleration structure and ray origins. */
descriptor_ranges[0].NumDescriptors = 2;
descriptor_ranges[1].RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_UAV; /* Output from raygen shader */
descriptor_ranges[1].OffsetInDescriptorsFromTableStart = 2;
descriptor_ranges[1].NumDescriptors = 1;
root_parameters[1].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
root_parameters[1].ParameterType = D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS;
root_parameters[1].Constants.Num32BitValues = 1;
root_parameters[1].Constants.RegisterSpace = 0;
root_parameters[1].Constants.ShaderRegister = 0;
hr = create_root_signature(device, &root_signature_desc, &global_rs);
ok(SUCCEEDED(hr), "Failed to create root signature, hr #%x.\n", hr);
}
/* Create local root signature. This defines how the data in the SBT for each individual shader is laid out. */
{
memset(&root_signature_desc, 0, sizeof(root_signature_desc));
memset(root_parameters, 0, sizeof(root_parameters));
memset(descriptor_ranges, 0, sizeof(descriptor_ranges));
/* 32BIT_CONSTANTS are 4 byte aligned. Descriptor tables take up 8 bytes instead of 4,
since the raw GPU VA of descriptor heap is placed in the buffer,
but it must still belong to the bound descriptor heap.
Root descriptors take up 8 bytes (raw pointers). */
root_signature_desc.NumParameters = 2;
root_signature_desc.pParameters = root_parameters;
/* We can have different implementation for local root sigs. */
root_signature_desc.Flags = D3D12_ROOT_SIGNATURE_FLAG_LOCAL_ROOT_SIGNATURE;
root_parameters[0].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
root_parameters[0].ParameterType = D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS;
root_parameters[0].Constants.Num32BitValues = 1;
root_parameters[0].Constants.RegisterSpace = 1;
root_parameters[0].Constants.ShaderRegister = 0;
root_parameters[1].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
root_parameters[1].ParameterType = D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS;
root_parameters[1].Constants.Num32BitValues = 1;
root_parameters[1].Constants.RegisterSpace = 1;
root_parameters[1].Constants.ShaderRegister = 1;
hr = create_root_signature(device, &root_signature_desc, &local_rs);
ok(SUCCEEDED(hr), "Failed to create root signature, hr #%x.\n", hr);
root_parameters[0].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
root_parameters[0].DescriptorTable.pDescriptorRanges = &table_range;
root_parameters[0].DescriptorTable.NumDescriptorRanges = 1;
table_range.OffsetInDescriptorsFromTableStart = 0;
table_range.RegisterSpace = 1;
table_range.BaseShaderRegister = 0;
table_range.NumDescriptors = 1;
table_range.RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_CBV;
root_parameters[1].ParameterType = D3D12_ROOT_PARAMETER_TYPE_CBV;
root_parameters[1].Descriptor.RegisterSpace = 1;
root_parameters[1].Descriptor.ShaderRegister = 1;
hr = create_root_signature(device, &root_signature_desc, &local_rs_table);
ok(SUCCEEDED(hr), "Failed to create root signature, hr #%x.\n", hr);
}
/* Create RT collection (triangles). */
{
D3D12_EXPORT_DESC dxil_exports[] = {
{ u"XRayClosest", u"RayClosest", 0 },
{ u"XRayAnyTriangle", u"RayAnyTriangle", 0 },
};
D3D12_HIT_GROUP_DESC hit_group;
memset(&hit_group, 0, sizeof(hit_group));
hit_group.Type = D3D12_HIT_GROUP_TYPE_TRIANGLES;
hit_group.ClosestHitShaderImport = u"XRayClosest";
hit_group.AnyHitShaderImport = u"XRayAnyTriangle";
hit_group.HitGroupExport = u"XRayHitTriangle";
rt_object_library_tri = create_rt_collection(&context,
ARRAY_SIZE(dxil_exports), dxil_exports,
&hit_group, global_rs, local_rs, mode);
}
/* Create RT collection (AABB). */
{
D3D12_EXPORT_DESC dxil_exports[] = {
{ u"XRayClosestAABB", u"RayClosest", 0 },
{ u"XRayAnyAABB", u"RayAnyAABB", 0 },
{ u"XRayIntersect", u"RayIntersect", 0 },
};
D3D12_HIT_GROUP_DESC hit_group;
memset(&hit_group, 0, sizeof(hit_group));
hit_group.Type = D3D12_HIT_GROUP_TYPE_PROCEDURAL_PRIMITIVE;
hit_group.ClosestHitShaderImport = u"XRayClosestAABB";
hit_group.AnyHitShaderImport = u"XRayAnyAABB";
hit_group.IntersectionShaderImport = u"XRayIntersect";
hit_group.HitGroupExport = u"XRayHitAABB";
rt_object_library_aabb = create_rt_collection(&context,
ARRAY_SIZE(dxil_exports), dxil_exports,
&hit_group, global_rs, local_rs, mode);
}
/* Create RT PSO. */
if (rt_object_library_tri && rt_object_library_aabb)
{
const WCHAR *table_export[] = { u"XRayMiss" };
D3D12_EXPORT_DESC dxil_exports[2] = {
{ u"XRayMiss", u"RayMiss", 0 },
{ u"XRayGen", u"RayGen", 0 },
};
unsigned int local_rs_table_index;
D3D12_HIT_GROUP_DESC hit_group;
struct rt_pso_factory factory;
unsigned int local_rs_index;
rt_pso_factory_init(&factory);
rt_pso_factory_add_default_node_mask(&factory);
if (mode == TEST_MODE_PSO_ADD_TO_STATE_OBJECT)
rt_pso_factory_add_state_object_config(&factory, D3D12_STATE_OBJECT_FLAG_ALLOW_STATE_OBJECT_ADDITIONS);
else
rt_pso_factory_add_state_object_config(&factory, D3D12_STATE_OBJECT_FLAG_NONE);
rt_pso_factory_add_global_root_signature(&factory, global_rs);
if (mode == TEST_MODE_PSO_SKIP_TRIANGLES)
rt_pso_factory_add_pipeline_config1(&factory, 1, D3D12_RAYTRACING_PIPELINE_FLAG_SKIP_TRIANGLES);
else if (mode == TEST_MODE_PSO_SKIP_AABBS)
rt_pso_factory_add_pipeline_config1(&factory, 1, D3D12_RAYTRACING_PIPELINE_FLAG_SKIP_PROCEDURAL_PRIMITIVES);
else
rt_pso_factory_add_pipeline_config(&factory, 1);
rt_pso_factory_add_shader_config(&factory, 8, 8);
/* All entry points are exported by default. Test with custom exports, because why not. */
rt_pso_factory_add_dxil_library(&factory, get_default_rt_lib(), ARRAY_SIZE(dxil_exports), dxil_exports);
local_rs_table_index = rt_pso_factory_add_local_root_signature(&factory, local_rs_table);
local_rs_index = rt_pso_factory_add_local_root_signature(&factory, local_rs);
/* Apparently, we have to point to a subobject in the array, otherwise, it just silently fails. */
rt_pso_factory_add_subobject_to_exports_association(&factory,
local_rs_table_index, ARRAY_SIZE(table_export), table_export);
rt_pso_factory_add_subobject_to_exports_association(&factory,
local_rs_index, 0, NULL);
/* Defer this. */
if (mode != TEST_MODE_PSO_ADD_TO_STATE_OBJECT)
{
rt_pso_factory_add_existing_collection(&factory, rt_object_library_tri, 0, NULL);
rt_pso_factory_add_existing_collection(&factory, rt_object_library_aabb, 0, NULL);
memset(&hit_group, 0, sizeof(hit_group));
hit_group.Type = D3D12_HIT_GROUP_TYPE_TRIANGLES;
hit_group.ClosestHitShaderImport = u"XRayClosest";
hit_group.HitGroupExport = u"XRayHit2";
rt_pso_factory_add_hit_group(&factory, &hit_group);
}
rt_pso = rt_pso_factory_compile(&context, &factory, D3D12_STATE_OBJECT_TYPE_RAYTRACING_PIPELINE);
if (mode != TEST_MODE_PSO_ADD_TO_STATE_OBJECT)
{
/* Docs say there should be ref-count of the collection, but apparently, that refcount is private. */
ref_count = ID3D12StateObject_AddRef(rt_object_library_tri);
ok(ref_count == 2, "Collection ref count is %u.\n", ref_count);
ID3D12StateObject_Release(rt_object_library_tri);
ref_count = ID3D12StateObject_AddRef(rt_object_library_aabb);
ok(ref_count == 2, "Collection ref count is %u.\n", ref_count);
ID3D12StateObject_Release(rt_object_library_aabb);
}
}
else
rt_pso = NULL;
/* Add two iterations of AddToStateObject so we have test coverage of that scenario. */
if (mode == TEST_MODE_PSO_ADD_TO_STATE_OBJECT && rt_pso)
{
D3D12_HIT_GROUP_DESC hit_group;
memset(&hit_group, 0, sizeof(hit_group));
hit_group.Type = D3D12_HIT_GROUP_TYPE_TRIANGLES;
hit_group.ClosestHitShaderImport = u"XRayClosest";
hit_group.HitGroupExport = u"XRayHit2";
rt_pso_added = rt_pso_add_to_state_object(context.device5, rt_pso, rt_object_library_tri, &hit_group);
ID3D12StateObject_Release(rt_pso);
rt_pso = rt_pso_added;
ref_count = ID3D12StateObject_AddRef(rt_object_library_tri);
ok(ref_count == 2, "Collection ref count is %u.\n", ref_count);
ID3D12StateObject_Release(rt_object_library_tri);
}
if (mode == TEST_MODE_PSO_ADD_TO_STATE_OBJECT && rt_pso)
{
uint8_t pre_ray_miss_data[D3D12_SHADER_IDENTIFIER_SIZE_IN_BYTES];
uint8_t pre_ray_gen_data[D3D12_SHADER_IDENTIFIER_SIZE_IN_BYTES];
uint8_t pre_hit_data[D3D12_SHADER_IDENTIFIER_SIZE_IN_BYTES];
ID3D12StateObjectProperties *combined_props;
static const WCHAR ray_miss[] = u"XRayMiss";
static const WCHAR ray_hit2[] = u"XRayHit2";
static const WCHAR ray_gen[] = u"XRayGen";
ID3D12StateObjectProperties *post_props;
ID3D12StateObjectProperties *pre_props;
uint8_t *combined_ray_miss;
uint8_t *combined_ray_gen;
uint8_t *combined_hit;
uint8_t *post_ray_miss;
uint8_t *post_ray_gen;
uint8_t *post_hit;
uint8_t *pre_ray_miss;
uint8_t *pre_ray_gen;
uint8_t *pre_hit;
ID3D12StateObject_QueryInterface(rt_pso, &IID_ID3D12StateObjectProperties, (void**)&pre_props);
pre_ray_gen = ID3D12StateObjectProperties_GetShaderIdentifier(pre_props, ray_gen);
pre_hit = ID3D12StateObjectProperties_GetShaderIdentifier(pre_props, ray_hit2);
pre_ray_miss = ID3D12StateObjectProperties_GetShaderIdentifier(pre_props, ray_miss);
memcpy(pre_ray_miss_data, pre_ray_miss, sizeof(pre_ray_miss_data));
memcpy(pre_ray_gen_data, pre_ray_gen, sizeof(pre_ray_gen_data));
memcpy(pre_hit_data, pre_hit, sizeof(pre_hit_data));
rt_pso_added = rt_pso_add_to_state_object(context.device5, rt_pso, rt_object_library_aabb, NULL);
ID3D12StateObject_QueryInterface(rt_pso, &IID_ID3D12StateObjectProperties, (void**)&post_props);
ID3D12StateObject_QueryInterface(rt_pso_added, &IID_ID3D12StateObjectProperties, (void**)&combined_props);
post_ray_gen = ID3D12StateObjectProperties_GetShaderIdentifier(post_props, ray_gen);
post_hit = ID3D12StateObjectProperties_GetShaderIdentifier(post_props, ray_hit2);
post_ray_miss = ID3D12StateObjectProperties_GetShaderIdentifier(post_props, ray_miss);
combined_ray_gen = ID3D12StateObjectProperties_GetShaderIdentifier(combined_props, ray_gen);
combined_hit = ID3D12StateObjectProperties_GetShaderIdentifier(combined_props, ray_hit2);
combined_ray_miss = ID3D12StateObjectProperties_GetShaderIdentifier(combined_props, ray_miss);
/* The docs do talk about taking some weird internal locks to deal with AddToStateObject(), so verify
* that we don't have to return the parent property pointer here. */
ok(pre_props == post_props, "Unexpected result in interface check.\n");
ok(combined_props != post_props, "Unexpected result in interface check.\n");
ok(pre_ray_gen == post_ray_gen, "Unexpected SBT pointers.\n");
ok(pre_hit == post_hit, "Unexpected SBT pointers.\n");
ok(pre_ray_miss == post_ray_miss, "Unexpected SBT pointers.\n");
/* Apparently, we have to inherit the pointer to the SBT directly. */
ok(combined_ray_gen == post_ray_gen, "Unexpected SBT pointers.\n");
ok(combined_hit == post_hit, "Unexpected SBT pointers.\n");
ok(combined_ray_miss == post_ray_miss, "Unexpected SBT pointers.\n");
/* Verify that we cannot modify the SBT data in place. */
ok(memcmp(combined_hit, pre_hit_data, sizeof(pre_hit_data)) == 0, "Detected variance for existing SBT entries.\n");
ok(memcmp(combined_ray_gen, pre_ray_gen_data, sizeof(pre_ray_gen_data)) == 0, "Detected variance for existing SBT entries.\n");
ok(memcmp(combined_ray_miss, pre_ray_miss_data, sizeof(pre_ray_miss_data)) == 0, "Detected variance for existing SBT entries.\n");
ID3D12StateObject_Release(rt_pso);
rt_pso = rt_pso_added;
ref_count = ID3D12StateObject_AddRef(rt_object_library_aabb);
ok(ref_count == 2, "Collection ref count is %u.\n", ref_count);
ID3D12StateObject_Release(rt_object_library_aabb);
ID3D12StateObjectProperties_Release(pre_props);
ID3D12StateObjectProperties_Release(post_props);
ID3D12StateObjectProperties_Release(combined_props);
}
/* Docs say that refcount should be held by RTPSO, but apparently it doesn't on native drivers. */
ID3D12RootSignature_AddRef(global_rs);
ID3D12RootSignature_AddRef(local_rs);
ref_count = ID3D12RootSignature_Release(global_rs);
ok(ref_count == 1, "Ref count %u != 1.\n", ref_count);
ref_count = ID3D12RootSignature_Release(local_rs);
ok(ref_count == 1, "Ref count %u != 1.\n", ref_count);
descriptor_heap = create_gpu_descriptor_heap(device, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, 4);
descriptor_size = ID3D12Device_GetDescriptorHandleIncrementSize(device, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
cpu_handle = ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(descriptor_heap);
gpu_handle = ID3D12DescriptorHeap_GetGPUDescriptorHandleForHeapStart(descriptor_heap);
/* Build SBT (Shader Binding Table) */
sbt_colors_buffer = NULL;
sbt = NULL;
if (rt_pso)
{
ID3D12StateObjectProperties *props;
sbt_colors[0][0] = 1000.0f;
sbt_colors[0][1] = 2000.0f;
for (i = 1; i < ARRAY_SIZE(sbt_colors); i++)
{
sbt_colors[i][0] = 2 * i + 1;
sbt_colors[i][1] = 2 * i + 2;
}
{
uint8_t padded[2048];
memcpy(padded + 0, &sbt_colors[0][0], sizeof(float));
memcpy(padded + 1024, &sbt_colors[0][1], sizeof(float));
sbt_colors_buffer = create_upload_buffer(device, sizeof(padded), padded);
}
/* Why this is a separate interface, we will never know ... */
if (SUCCEEDED(ID3D12StateObject_QueryInterface(rt_pso, &IID_ID3D12StateObjectProperties, (void **)&props)))
{
static const WCHAR ray_tri_intersect[] = u"XRayHitTriangle::intersection";
static const WCHAR ray_aabb_intersect[] = u"XRayHitAABB::intersection";
static const WCHAR ray_tri_closest[] = u"XRayHitTriangle::closesthit";
static const WCHAR ray_aabb_closest[] = u"XRayHitAABB::closesthit";
static const WCHAR ray_tri_anyhit[] = u"XRayHitTriangle::anyhit";
static const WCHAR ray_aabb_anyhit[] = u"XRayHitAABB::anyhit";
static const WCHAR ray_broken3[] = u"XRayHitTriangle::X";
static const WCHAR ray_broken2[] = u"XRayHitTriangle::";
static const WCHAR ray_broken1[] = u"XRayHitTriangle:";
static const WCHAR ray_broken0[] = u"XRayHitTriangle";
static const WCHAR ray_hit_tri[] = u"XRayHitTriangle";
static const WCHAR ray_hit_aabb[] = u"XRayHitAABB";
static const WCHAR ray_miss[] = u"XRayMiss";
static const WCHAR ray_hit2[] = u"XRayHit2";
static const WCHAR ray_gen[] = u"XRayGen";
ID3D12StateObject *tmp_rt_pso;
const void *ray_hit_aabb_sbt;
unsigned int min_stack_size;
const void *ray_miss_sbt;
const void *ray_gen_sbt;
const void *ray_hit_sbt;
const void *ray_hit_sbt2;
unsigned int stack_size;
uint8_t sbt_data[4096];
hr = ID3D12StateObjectProperties_QueryInterface(props, &IID_ID3D12StateObject, (void **)&tmp_rt_pso);
ok(SUCCEEDED(hr), "Failed to query state object interface from properties.\n");
if (SUCCEEDED(hr))
ID3D12StateObject_Release(tmp_rt_pso);
/* Test reference count semantics for non-derived interface. */
ref_count = ID3D12StateObjectProperties_AddRef(props);
ok(ref_count == 3, "Unexpected refcount %u.\n", ref_count);
ref_count = ID3D12StateObjectProperties_AddRef(props);
ok(ref_count == 4, "Unexpected refcount %u.\n", ref_count);
ref_count = ID3D12StateObject_AddRef(rt_pso);
ok(ref_count == 5, "Unexpected refcount %u.\n", ref_count);
ref_count = ID3D12StateObject_AddRef(rt_pso);
ok(ref_count == 6, "Unexpected refcount %u.\n", ref_count);
ref_count = ID3D12StateObjectProperties_Release(props);
ok(ref_count == 5, "Unexpected refcount %u.\n", ref_count);
ref_count = ID3D12StateObjectProperties_Release(props);
ok(ref_count == 4, "Unexpected refcount %u.\n", ref_count);
ref_count = ID3D12StateObject_Release(rt_pso);
ok(ref_count == 3, "Unexpected refcount %u.\n", ref_count);
ref_count = ID3D12StateObject_Release(rt_pso);
ok(ref_count == 2, "Unexpected refcount %u.\n", ref_count);
/* AMD Windows returns 0 here for all stack sizes. There is no well defined return value we expect here,
* but verify we return something sane. */
stack_size = ID3D12StateObjectProperties_GetShaderStackSize(props, ray_gen);
ok(stack_size <= 8, "Stack size %u > 8.\n", stack_size);
stack_size = ID3D12StateObjectProperties_GetShaderStackSize(props, ray_miss);
ok(stack_size <= 8, "Stack size %u > 8.\n", stack_size);
stack_size = ID3D12StateObjectProperties_GetShaderStackSize(props, ray_tri_closest);
ok(stack_size <= 8, "Stack size %u > 8.\n", stack_size);
stack_size = ID3D12StateObjectProperties_GetShaderStackSize(props, ray_tri_anyhit);
ok(stack_size <= 8, "Stack size %u > 8.\n", stack_size);
stack_size = ID3D12StateObjectProperties_GetShaderStackSize(props, ray_tri_intersect);
ok(stack_size == ~0u, "Stack size %u != UINT_MAX.\n", stack_size);
stack_size = ID3D12StateObjectProperties_GetShaderStackSize(props, ray_aabb_closest);
ok(stack_size <= 8, "Stack size %u > 8.\n", stack_size);
stack_size = ID3D12StateObjectProperties_GetShaderStackSize(props, ray_aabb_anyhit);
ok(stack_size <= 8, "Stack size %u > 8.\n", stack_size);
stack_size = ID3D12StateObjectProperties_GetShaderStackSize(props, ray_aabb_intersect);
ok(stack_size <= 8, "Stack size %u > 8.\n", stack_size);
stack_size = ID3D12StateObjectProperties_GetShaderStackSize(props, ray_broken0);
ok(stack_size == ~0u, "Stack size %u != UINT_MAX.\n", stack_size);
stack_size = ID3D12StateObjectProperties_GetShaderStackSize(props, ray_broken1);
ok(stack_size == ~0u, "Stack size %u != UINT_MAX.\n", stack_size);
stack_size = ID3D12StateObjectProperties_GetShaderStackSize(props, ray_broken2);
ok(stack_size == ~0u, "Stack size %u != UINT_MAX.\n", stack_size);
stack_size = ID3D12StateObjectProperties_GetShaderStackSize(props, ray_broken3);
ok(stack_size == ~0u, "Stack size %u != UINT_MAX.\n", stack_size);
stack_size = ID3D12StateObjectProperties_GetPipelineStackSize(props);
ok(stack_size <= 8, "Stack size %u < 8.\n", stack_size);
/* Apparently even if we set stack size here, it will be clamped to the conservative stack size on AMD?
* Driver behavior on NV and AMD is different here, choose NV behavior as it makes more sense. */
min_stack_size = stack_size;
ID3D12StateObjectProperties_SetPipelineStackSize(props, 256);
stack_size = ID3D12StateObjectProperties_GetPipelineStackSize(props);
ok(stack_size <= min_stack_size || stack_size == 256, "Stack size %u > %u && %u != 256.\n", stack_size, min_stack_size, stack_size);
ray_gen_sbt = ID3D12StateObjectProperties_GetShaderIdentifier(props, ray_gen);
ray_hit_sbt = ID3D12StateObjectProperties_GetShaderIdentifier(props, ray_hit_tri);
ray_hit_sbt2 = ID3D12StateObjectProperties_GetShaderIdentifier(props, ray_hit2);
ray_miss_sbt = ID3D12StateObjectProperties_GetShaderIdentifier(props, ray_miss);
ray_hit_aabb_sbt = ID3D12StateObjectProperties_GetShaderIdentifier(props, ray_hit_aabb);
ok(!!ray_gen_sbt, "Failed to get SBT.\n");
ok(!!ray_hit_sbt, "Failed to get SBT.\n");
ok(!!ray_hit_sbt2, "Failed to get SBT.\n");
ok(!!ray_miss_sbt, "Failed to get SBT.\n");
ok(!!ray_hit_aabb_sbt, "Failed to get SBT.\n");
memcpy(sbt_data, ray_miss_sbt, D3D12_SHADER_IDENTIFIER_SIZE_IN_BYTES);
{
bool use_aabb, use_anyhit_shader;
const void *active_sbt;
for (instance = 0; instance < NUM_UNMASKED_INSTANCES; instance++)
{
for (geom = 0; geom < NUM_GEOM_DESC; geom++)
{
i = instance * NUM_GEOM_DESC + geom;
use_aabb = instance_index_is_aabb(instance);
use_anyhit_shader = !!(i & 3);
if (use_aabb)
active_sbt = ray_hit_aabb_sbt;
else
active_sbt = use_anyhit_shader ? ray_hit_sbt : ray_hit_sbt2;
memcpy(sbt_data + (i + 1) * 64, active_sbt, D3D12_SHADER_IDENTIFIER_SIZE_IN_BYTES);
}
}
}
memcpy(sbt_data + (NUM_GEOM_DESC * NUM_UNMASKED_INSTANCES + 1) * 64, ray_gen_sbt, D3D12_SHADER_IDENTIFIER_SIZE_IN_BYTES);
/* Local root signature data is placed after the shader identifier at offset 32 bytes. */
/* For miss shader, we use a different local root signature.
* Tests that we handle local tables + local root descriptor. */
{
UINT64 miss_sbt[2];
miss_sbt[0] = ID3D12DescriptorHeap_GetGPUDescriptorHandleForHeapStart(descriptor_heap).ptr + 3 * descriptor_size;
miss_sbt[1] = ID3D12Resource_GetGPUVirtualAddress(sbt_colors_buffer) + 1024;
memcpy(sbt_data + D3D12_SHADER_IDENTIFIER_SIZE_IN_BYTES, miss_sbt, sizeof(miss_sbt));
}
for (i = 1; i < ARRAY_SIZE(sbt_colors); i++)
memcpy(sbt_data + D3D12_SHADER_IDENTIFIER_SIZE_IN_BYTES + 64 * i, sbt_colors[i], sizeof(sbt_colors[i]));
sbt = create_upload_buffer(device, sizeof(sbt_data), sbt_data);
ID3D12StateObjectProperties_Release(props);
}
else
{
destroy_raytracing_test_context(&context);
return;
}
}
{
/* For test, we want to hit miss shader, then hit group indices in order. */
float ray_pos[NUM_GEOM_DESC * NUM_UNMASKED_INSTANCES + 1][2];
unsigned int x, y;
/* Should hit instance 2, but gets masked out. */
ray_pos[0][0] = 0.0f;
ray_pos[0][1] = -INSTANCE_OFFSET_Y;
for (y = 0; y < NUM_UNMASKED_INSTANCES; y++)
{
for (x = 0; x < NUM_GEOM_DESC; x++)
{
ray_pos[y * NUM_GEOM_DESC + x + 1][0] = INSTANCE_GEOM_SCALE * GEOM_OFFSET_X * (float)x; /* Instance transform will scale X offset from 10 * index to 5 * index. */
ray_pos[y * NUM_GEOM_DESC + x + 1][1] = INSTANCE_OFFSET_Y * (float)y;
}
}
ray_colors = create_default_buffer(device, sizeof(sbt_colors), D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
ray_positions = create_upload_buffer(device, sizeof(ray_pos), ray_pos);
}
{
D3D12_SHADER_RESOURCE_VIEW_DESC as_desc;
D3D12_GPU_VIRTUAL_ADDRESS rtases[2];
memset(&as_desc, 0, sizeof(as_desc));
as_desc.ViewDimension = D3D12_SRV_DIMENSION_RAYTRACING_ACCELERATION_STRUCTURE;
as_desc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
as_desc.Format = DXGI_FORMAT_UNKNOWN;
as_desc.RaytracingAccelerationStructure.Location = ID3D12Resource_GetGPUVirtualAddress(test_rtases.top_acceleration_structures[2]);
ID3D12Device_CreateShaderResourceView(device, NULL, &as_desc, cpu_handle);
cpu_handle.ptr += descriptor_size;
rtases[0] = ID3D12Resource_GetGPUVirtualAddress(test_rtases.bottom_acceleration_structures_tri[0]);
rtases[1] = ID3D12Resource_GetGPUVirtualAddress(test_rtases.top_acceleration_structures[0]);
/* Emitting this is not COPY_DEST, but UNORDERED_ACCESS for some bizarre reason. */
postbuild_desc[0].InfoType = D3D12_RAYTRACING_ACCELERATION_STRUCTURE_POSTBUILD_INFO_COMPACTED_SIZE;
postbuild_desc[0].DestBuffer = ID3D12Resource_GetGPUVirtualAddress(postbuild_buffer) + 8 * sizeof(uint64_t);
postbuild_desc[1].InfoType = D3D12_RAYTRACING_ACCELERATION_STRUCTURE_POSTBUILD_INFO_CURRENT_SIZE;
postbuild_desc[1].DestBuffer = postbuild_desc[0].DestBuffer + 2 * sizeof(D3D12_RAYTRACING_ACCELERATION_STRUCTURE_POSTBUILD_INFO_COMPACTED_SIZE_DESC);
postbuild_desc[2].InfoType = D3D12_RAYTRACING_ACCELERATION_STRUCTURE_POSTBUILD_INFO_SERIALIZATION;
postbuild_desc[2].DestBuffer = postbuild_desc[1].DestBuffer + 2 * sizeof(D3D12_RAYTRACING_ACCELERATION_STRUCTURE_POSTBUILD_INFO_CURRENT_SIZE_DESC);
ID3D12GraphicsCommandList4_EmitRaytracingAccelerationStructurePostbuildInfo(command_list4, &postbuild_desc[0], 2, rtases);
ID3D12GraphicsCommandList4_EmitRaytracingAccelerationStructurePostbuildInfo(command_list4, &postbuild_desc[1], 2, rtases);
ID3D12GraphicsCommandList4_EmitRaytracingAccelerationStructurePostbuildInfo(command_list4, &postbuild_desc[2], 2, rtases);
transition_resource_state(command_list, postbuild_buffer, D3D12_RESOURCE_STATE_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_SOURCE);
ID3D12GraphicsCommandList_CopyResource(command_list, postbuild_readback, postbuild_buffer);
}
{
D3D12_SHADER_RESOURCE_VIEW_DESC ray_pos_desc;
memset(&ray_pos_desc, 0, sizeof(ray_pos_desc));
ray_pos_desc.ViewDimension = D3D12_SRV_DIMENSION_BUFFER;
ray_pos_desc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
ray_pos_desc.Format = DXGI_FORMAT_UNKNOWN;
ray_pos_desc.Buffer.FirstElement = 0;
ray_pos_desc.Buffer.NumElements = NUM_GEOM_DESC * NUM_UNMASKED_INSTANCES + 1;
ray_pos_desc.Buffer.StructureByteStride = 8;
ID3D12Device_CreateShaderResourceView(device, ray_positions, &ray_pos_desc, cpu_handle);
cpu_handle.ptr += descriptor_size;
}
{
D3D12_UNORDERED_ACCESS_VIEW_DESC ray_col_desc;
memset(&ray_col_desc, 0, sizeof(ray_col_desc));
ray_col_desc.ViewDimension = D3D12_UAV_DIMENSION_BUFFER;
ray_col_desc.Format = DXGI_FORMAT_UNKNOWN;
ray_col_desc.Buffer.FirstElement = 0;
ray_col_desc.Buffer.NumElements = NUM_GEOM_DESC * NUM_UNMASKED_INSTANCES + 1;
ray_col_desc.Buffer.StructureByteStride = 8;
ID3D12Device_CreateUnorderedAccessView(device, ray_colors, NULL, &ray_col_desc, cpu_handle);
cpu_handle.ptr += descriptor_size;
}
if (sbt_colors_buffer)
{
D3D12_CONSTANT_BUFFER_VIEW_DESC miss_view_desc;
memset(&miss_view_desc, 0, sizeof(miss_view_desc));
miss_view_desc.BufferLocation = ID3D12Resource_GetGPUVirtualAddress(sbt_colors_buffer);
miss_view_desc.SizeInBytes = ID3D12Resource_GetDesc(sbt_colors_buffer).Width;
ID3D12Device_CreateConstantBufferView(device, &miss_view_desc, cpu_handle);
cpu_handle.ptr += descriptor_size;
}
ID3D12GraphicsCommandList4_SetComputeRootSignature(command_list4, global_rs);
ID3D12GraphicsCommandList4_SetPipelineState1(command_list4, rt_pso);
ID3D12GraphicsCommandList4_SetDescriptorHeaps(command_list4, 1, &descriptor_heap);
ID3D12GraphicsCommandList4_SetComputeRootDescriptorTable(command_list4, 0, gpu_handle);
if (sbt)
{
D3D12_DISPATCH_RAYS_DESC desc;
uint32_t flags;
memset(&desc, 0, sizeof(desc));
desc.Width = NUM_GEOM_DESC * NUM_UNMASKED_INSTANCES + 1;
desc.Height = 1;
desc.Depth = 1;
desc.MissShaderTable.StartAddress = ID3D12Resource_GetGPUVirtualAddress(sbt);
desc.MissShaderTable.SizeInBytes = 64;
desc.MissShaderTable.StrideInBytes = 64;
desc.HitGroupTable.StartAddress = desc.MissShaderTable.StartAddress + desc.MissShaderTable.SizeInBytes;
desc.HitGroupTable.StrideInBytes = 64;
desc.HitGroupTable.SizeInBytes = 64 * NUM_GEOM_DESC * NUM_UNMASKED_INSTANCES;
desc.RayGenerationShaderRecord.SizeInBytes = 64;
desc.RayGenerationShaderRecord.StartAddress = desc.HitGroupTable.StartAddress + desc.HitGroupTable.SizeInBytes;
flags = test_mode_to_trace_flags(mode);
ID3D12GraphicsCommandList4_SetComputeRoot32BitConstant(command_list4, 1, flags, 0);
ID3D12GraphicsCommandList4_DispatchRays(command_list4, &desc);
}
transition_resource_state(command_list, ray_colors, D3D12_RESOURCE_STATE_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_SOURCE);
get_buffer_readback_with_command_list(ray_colors, DXGI_FORMAT_UNKNOWN, &rb, queue, command_list);
{
float expected_x, expected_y;
bool expect_hit, use_aabb;
bool culled;
float x, y;
for (instance = 0; instance < NUM_UNMASKED_INSTANCES; instance++)
{
for (geom = 0; geom < NUM_GEOM_DESC; geom++)
{
use_aabb = instance_index_is_aabb(instance);
i = NUM_GEOM_DESC * instance + geom;
x = get_readback_float(&rb, 2 * (i + 1), 0);
y = get_readback_float(&rb, 2 * (i + 1) + 1, 0);
if (mode == TEST_MODE_TRACE_RAY_FORCE_OPAQUE)
expect_hit = true;
else if (mode == TEST_MODE_TRACE_RAY_FORCE_NON_OPAQUE)
expect_hit = false;
else if (instance == 0 || instance == 2)
expect_hit = true; /* Force opaque on instance desc. */
else if (instance == 1 || instance == 3)
expect_hit = false; /* Force non-opaque on instance desc, any hit -> miss will trigger. */
else
expect_hit = !!(geom & 1); /* Geom desc has either NONE or OPAQUE. */
if (!use_aabb && (i & 3) == 0)
expect_hit = true; /* Use an SBT without any-hit shader, so opaque flags don't matter. */
if ((use_aabb && (mode == TEST_MODE_TRACE_RAY_SKIP_AABBS || mode == TEST_MODE_PSO_SKIP_AABBS)) ||
(!use_aabb && (mode == TEST_MODE_TRACE_RAY_SKIP_TRIANGLES || mode == TEST_MODE_PSO_SKIP_TRIANGLES)))
{
expect_hit = false;
culled = true;
}
else
culled = false;
if (expect_hit)
{
expected_x = sbt_colors[i + 1][0];
expected_y = sbt_colors[i + 1][1];
}
else
{
expected_x = sbt_colors[0][0]; /* Miss shader is run. */
expected_y = sbt_colors[0][1];
if (!culled)
{
if (use_aabb)
expected_y += 1.0f; /* Any-hit shader accumulates .y by 1.0f here. */
else
expected_x += 1.0f; /* Any-hit shader accumulates .x by 1.0f here. */
}
}
ok(x == expected_x, "Ray color [%u].x mismatch (%f != %f).\n", i, x, expected_x);
ok(y == expected_y, "Ray color [%u].y mismatch (%f != %f).\n", i, y, expected_y);
}
}
x = get_readback_float(&rb, 0, 0);
y = get_readback_float(&rb, 1, 0);
expected_x = sbt_colors[0][0]; /* Only miss shader is run. */
expected_y = sbt_colors[0][1];
ok(x == expected_x, "Miss ray color.x mismatch (%f != %f).\n", x, expected_x);
ok(y == expected_y, "Miss ray color.y mismatch (%f != %f).\n", y, expected_y);
}
release_resource_readback(&rb);
{
struct post_info
{
D3D12_RAYTRACING_ACCELERATION_STRUCTURE_POSTBUILD_INFO_COMPACTED_SIZE_DESC compacted;
D3D12_RAYTRACING_ACCELERATION_STRUCTURE_POSTBUILD_INFO_CURRENT_SIZE_DESC current;
D3D12_RAYTRACING_ACCELERATION_STRUCTURE_POSTBUILD_INFO_SERIALIZATION_DESC serialize;
} top[2], bottom[2];
uint64_t *mapped;
hr = ID3D12Resource_Map(postbuild_readback, 0, NULL, (void **)&mapped);
ok(SUCCEEDED(hr), "Failed to map postbuild readback.\n");
if (SUCCEEDED(hr))
{
memcpy(&bottom[0], mapped + 0, sizeof(struct post_info));
memcpy(&top[0], mapped + 4, sizeof(struct post_info));
memcpy(&bottom[1].compacted, mapped + 8, sizeof(bottom[1].compacted));
memcpy(&top[1].compacted, mapped + 9, sizeof(top[1].compacted));
memcpy(&bottom[1].current, mapped + 10, sizeof(bottom[1].current));
memcpy(&top[1].current, mapped + 11, sizeof(top[1].current));
memcpy(&bottom[1].serialize, mapped + 12, sizeof(bottom[1].serialize));
memcpy(&top[1].serialize, mapped + 14, sizeof(top[1].serialize));
ok(memcmp(&top[0], &top[1], sizeof(top[0])) == 0, "Size mismatch.\n");
ok(memcmp(&bottom[0], &bottom[1], sizeof(bottom[0])) == 0, "Size mismatch.\n");
/* First sanity check that output from BuildRTAS and EmitPostbuildInfo() match up. */
ok(bottom[0].compacted.CompactedSizeInBytes > 0, "Compacted size for bottom acceleration structure is %u.\n", (unsigned int)bottom[0].compacted.CompactedSizeInBytes);
ok(top[0].compacted.CompactedSizeInBytes > 0, "Compacted size for top acceleration structure is %u.\n", (unsigned int)top[0].compacted.CompactedSizeInBytes);
/* CURRENT_SIZE cannot be queried in Vulkan directly. It should be possible to emulate it with a side buffer which we update on RTAS build,
* but ignore it for the time being, since it's only really relevant for tools. */
todo ok(bottom[0].current.CurrentSizeInBytes > 0, "Current size for bottom acceleration structure is %u.\n", (unsigned int)bottom[0].current.CurrentSizeInBytes);
todo ok(top[0].current.CurrentSizeInBytes > 0, "Current size for top acceleration structure is %u.\n", (unsigned int)top[0].current.CurrentSizeInBytes);
/* Compacted size must be less-or-equal to current size. Cannot pass since we don't have current size. */
todo ok(bottom[0].compacted.CompactedSizeInBytes <= bottom[0].current.CurrentSizeInBytes,
"Compacted size %u > Current size %u\n", (unsigned int)bottom[0].compacted.CompactedSizeInBytes, (unsigned int)bottom[0].current.CurrentSizeInBytes);
todo ok(top[0].compacted.CompactedSizeInBytes <= top[0].current.CurrentSizeInBytes,
"Compacted size %u > Current size %u\n", (unsigned int)top[0].compacted.CompactedSizeInBytes, (unsigned int)top[0].current.CurrentSizeInBytes);
ok(bottom[0].serialize.SerializedSizeInBytes > 0, "Serialized size for bottom acceleration structure is %u.\n", (unsigned int)bottom[0].serialize.SerializedSizeInBytes);
ok(bottom[0].serialize.NumBottomLevelAccelerationStructurePointers == 0, "NumBottomLevel pointers is %u.\n", (unsigned int)bottom[0].serialize.NumBottomLevelAccelerationStructurePointers);
ok(top[0].serialize.SerializedSizeInBytes > 0, "Serialized size for top acceleration structure is %u.\n", (unsigned int)top[0].serialize.SerializedSizeInBytes);
todo ok(top[0].serialize.NumBottomLevelAccelerationStructurePointers == NUM_UNMASKED_INSTANCES + 1,
"NumBottomLevel pointers is %u.\n", (unsigned int)top[0].serialize.NumBottomLevelAccelerationStructurePointers);
ID3D12Resource_Unmap(postbuild_readback, 0, NULL);
}
}
destroy_test_geometry(&test_geom);
destroy_rt_geometry(&test_rtases);
if (sbt_colors_buffer)
ID3D12Resource_Release(sbt_colors_buffer);
ID3D12RootSignature_Release(global_rs);
ID3D12RootSignature_Release(local_rs);
ID3D12RootSignature_Release(local_rs_table);
if (rt_pso)
ID3D12StateObject_Release(rt_pso);
if (rt_object_library_tri)
ID3D12StateObject_Release(rt_object_library_tri);
if (rt_object_library_aabb)
ID3D12StateObject_Release(rt_object_library_aabb);
ID3D12Resource_Release(ray_colors);
ID3D12Resource_Release(ray_positions);
ID3D12DescriptorHeap_Release(descriptor_heap);
if (sbt)
ID3D12Resource_Release(sbt);
ID3D12Resource_Release(postbuild_readback);
ID3D12Resource_Release(postbuild_buffer);
destroy_raytracing_test_context(&context);
}
void test_raytracing(void)
{
struct test
{
enum rt_test_mode mode;
D3D12_RAYTRACING_TIER minimum_tier;
const char *desc;
};
static const struct test tests[] = {
{ TEST_MODE_PLAIN, D3D12_RAYTRACING_TIER_1_0, "Plain" },
{ TEST_MODE_TRACE_RAY_FORCE_OPAQUE, D3D12_RAYTRACING_TIER_1_0, "TraceRayForceOpaque" },
{ TEST_MODE_TRACE_RAY_FORCE_NON_OPAQUE, D3D12_RAYTRACING_TIER_1_0, "TraceRayForceNonOpaque" },
{ TEST_MODE_TRACE_RAY_SKIP_TRIANGLES, D3D12_RAYTRACING_TIER_1_1, "TraceRaySkipTriangles" },
{ TEST_MODE_TRACE_RAY_SKIP_AABBS, D3D12_RAYTRACING_TIER_1_1, "TraceRaySkipAABBs" },
{ TEST_MODE_PSO_SKIP_TRIANGLES, D3D12_RAYTRACING_TIER_1_1, "PSOSkipTriangles" },
{ TEST_MODE_PSO_SKIP_AABBS, D3D12_RAYTRACING_TIER_1_1, "PSOSkipAABBs" },
{ TEST_MODE_PSO_ADD_TO_STATE_OBJECT, D3D12_RAYTRACING_TIER_1_1, "AddToStateObject" },
};
unsigned int i;
for (i = 0; i < ARRAY_SIZE(tests); i++)
{
vkd3d_test_set_context("Test: %s", tests[i].desc);
test_raytracing_pipeline(tests[i].mode, tests[i].minimum_tier);
}
vkd3d_test_set_context(NULL);
}
static void test_rayquery_pipeline(enum rt_test_mode mode)
{
/* Intended to mirror the test case for RTPSO closely. */
#define THREADGROUP_SIZE 64
D3D12_ROOT_SIGNATURE_DESC root_signature_desc;
D3D12_ROOT_PARAMETER root_parameters[4];
ID3D12GraphicsCommandList *command_list;
struct raytracing_test_context context;
struct test_rt_geometry test_rtases;
ID3D12RootSignature *root_signature;
const float miss_color_x = 1000.0f;
const float miss_color_y = 2000.0f;
struct test_geometry test_geom;
unsigned int i, instance, geom;
ID3D12Resource *ray_positions;
ID3D12Resource *ray_results;
struct resource_readback rb;
ID3D12CommandQueue *queue;
ID3D12PipelineState *pso;
ID3D12Device *device;
HRESULT hr;
if (!init_raytracing_test_context(&context, D3D12_RAYTRACING_TIER_1_1))
return;
device = context.context.device;
command_list = context.context.list;
queue = context.context.queue;
memset(&root_signature_desc, 0, sizeof(root_signature_desc));
root_signature_desc.NumParameters = ARRAY_SIZE(root_parameters);
root_signature_desc.pParameters = root_parameters;
root_parameters[0].ParameterType = D3D12_ROOT_PARAMETER_TYPE_SRV;
root_parameters[0].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
root_parameters[0].Descriptor.ShaderRegister = 0;
root_parameters[0].Descriptor.RegisterSpace = 0;
root_parameters[1].ParameterType = D3D12_ROOT_PARAMETER_TYPE_SRV;
root_parameters[1].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
root_parameters[1].Descriptor.ShaderRegister = 1;
root_parameters[1].Descriptor.RegisterSpace = 0;
root_parameters[2].ParameterType = D3D12_ROOT_PARAMETER_TYPE_UAV;
root_parameters[2].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
root_parameters[2].Descriptor.ShaderRegister = 0;
root_parameters[2].Descriptor.RegisterSpace = 0;
root_parameters[3].ParameterType = D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS;
root_parameters[3].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
root_parameters[3].Constants.Num32BitValues = 3;
root_parameters[3].Constants.RegisterSpace = 0;
root_parameters[3].Constants.ShaderRegister = 0;
hr = create_root_signature(device, &root_signature_desc, &root_signature);
ok(SUCCEEDED(hr), "Failed to create root signature, hr #%x.\n", hr);
pso = create_compute_pipeline_state(device, root_signature, get_rayquery_shader());
init_test_geometry(device, &test_geom);
init_rt_geometry(&context, &test_rtases, &test_geom,
NUM_GEOM_DESC, GEOM_OFFSET_X,
NUM_UNMASKED_INSTANCES, INSTANCE_GEOM_SCALE, INSTANCE_OFFSET_Y, 0);
{
/* For test, we want to hit miss shader, then hit group indices in order. */
float ray_pos[THREADGROUP_SIZE][2];
unsigned int x, y;
memset(ray_pos, 0, sizeof(ray_pos));
/* Should hit instance 2, but gets masked out. */
ray_pos[0][0] = 0.0f;
ray_pos[0][1] = -INSTANCE_OFFSET_Y;
for (y = 0; y < NUM_UNMASKED_INSTANCES; y++)
{
for (x = 0; x < NUM_GEOM_DESC; x++)
{
ray_pos[y * NUM_GEOM_DESC + x + 1][0] = INSTANCE_GEOM_SCALE * GEOM_OFFSET_X * (float)x; /* Instance transform will scale X offset from 10 * index to 5 * index. */
ray_pos[y * NUM_GEOM_DESC + x + 1][1] = INSTANCE_OFFSET_Y * (float)y;
}
}
ray_positions = create_upload_buffer(device, sizeof(ray_pos), ray_pos);
ray_results = create_default_buffer(device, sizeof(ray_pos),
D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
}
ID3D12GraphicsCommandList_SetComputeRootSignature(command_list, root_signature);
ID3D12GraphicsCommandList_SetPipelineState(command_list, pso);
ID3D12GraphicsCommandList_SetComputeRootShaderResourceView(command_list, 0,
ID3D12Resource_GetGPUVirtualAddress(test_rtases.top_acceleration_structures[0]));
ID3D12GraphicsCommandList_SetComputeRootShaderResourceView(command_list, 1,
ID3D12Resource_GetGPUVirtualAddress(ray_positions));
ID3D12GraphicsCommandList_SetComputeRootUnorderedAccessView(command_list, 2,
ID3D12Resource_GetGPUVirtualAddress(ray_results));
{
struct { float miss_color[2]; uint32_t flags; } data;
data.miss_color[0] = miss_color_x;
data.miss_color[1] = miss_color_y;
data.flags = test_mode_to_trace_flags(mode);
ID3D12GraphicsCommandList_SetComputeRoot32BitConstants(command_list, 3, 3, &data, 0);
}
ID3D12GraphicsCommandList_Dispatch(command_list, 1, 1, 1);
transition_resource_state(command_list, ray_results,
D3D12_RESOURCE_STATE_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_SOURCE);
get_buffer_readback_with_command_list(ray_results, DXGI_FORMAT_R32_FLOAT, &rb, queue, command_list);
{
float expected_x, expected_y;
bool expect_hit, use_aabb;
bool culled;
float x, y;
for (instance = 0; instance < NUM_UNMASKED_INSTANCES; instance++)
{
for (geom = 0; geom < NUM_GEOM_DESC; geom++)
{
use_aabb = instance_index_is_aabb(instance);
i = NUM_GEOM_DESC * instance + geom;
x = get_readback_float(&rb, 2 * (i + 1), 0);
y = get_readback_float(&rb, 2 * (i + 1) + 1, 0);
if (mode == TEST_MODE_TRACE_RAY_FORCE_OPAQUE)
expect_hit = true;
else if (mode == TEST_MODE_TRACE_RAY_FORCE_NON_OPAQUE)
expect_hit = false;
else if (instance == 0 || instance == 2)
expect_hit = true; /* Force opaque on instance desc. */
else if (instance == 1 || instance == 3)
expect_hit = false; /* Force non-opaque on instance desc, any hit -> miss will trigger. */
else
expect_hit = !!(geom & 1); /* Geom desc has either NONE or OPAQUE. */
if ((use_aabb && mode == TEST_MODE_TRACE_RAY_SKIP_AABBS) ||
(!use_aabb && mode == TEST_MODE_TRACE_RAY_SKIP_TRIANGLES))
{
expect_hit = false;
culled = true;
}
else
culled = false;
if (expect_hit)
{
expected_x = (float)i + 1.0f; /* Closest hit case. */
expected_y = (float)i + 2.0f;
}
else
{
expected_x = 1000.0f; /* Miss case */
expected_y = 2000.0f;
if (!culled)
{
if (use_aabb)
expected_y += 1.0f;
else
expected_x += 1.0f;
}
}
ok(x == expected_x, "Ray color [%u].x mismatch (%f != %f).\n", i, x, expected_x);
ok(y == expected_y, "Ray color [%u].y mismatch (%f != %f).\n", i, y, expected_y);
}
}
x = get_readback_float(&rb, 0, 0);
y = get_readback_float(&rb, 1, 0);
expected_x = 1000.0f;
expected_y = 2000.0f;
ok(x == expected_x, "Miss ray color.x mismatch (%f != %f).\n", x, expected_x);
ok(y == expected_y, "Miss ray color.y mismatch (%f != %f).\n", y, expected_y);
}
release_resource_readback(&rb);
destroy_test_geometry(&test_geom);
destroy_rt_geometry(&test_rtases);
ID3D12Resource_Release(ray_positions);
ID3D12Resource_Release(ray_results);
ID3D12RootSignature_Release(root_signature);
ID3D12PipelineState_Release(pso);
destroy_raytracing_test_context(&context);
}
void test_rayquery(void)
{
struct test
{
enum rt_test_mode mode;
const char *desc;
};
static const struct test tests[] = {
{ TEST_MODE_PLAIN, "Plain" },
{ TEST_MODE_TRACE_RAY_FORCE_OPAQUE, "TraceRayForceOpaque" },
{ TEST_MODE_TRACE_RAY_FORCE_NON_OPAQUE, "TraceRayForceNonOpaque" },
{ TEST_MODE_TRACE_RAY_SKIP_TRIANGLES, "TraceRaySkipTriangles" },
{ TEST_MODE_TRACE_RAY_SKIP_AABBS, "TraceRaySkipAABBs" },
};
unsigned int i;
for (i = 0; i < ARRAY_SIZE(tests); i++)
{
vkd3d_test_set_context("Test: %s", tests[i].desc);
test_rayquery_pipeline(tests[i].mode);
}
vkd3d_test_set_context(NULL);
}
void test_raytracing_local_rs_static_sampler(void)
{
ID3D12GraphicsCommandList4 *command_list4;
ID3D12GraphicsCommandList *command_list;
struct raytracing_test_context context;
struct test_rt_geometry test_rtases;
ID3D12RootSignature *local_rs[2];
struct test_geometry test_geom;
ID3D12RootSignature *global_rs;
struct resource_readback rb;
ID3D12DescriptorHeap *heap;
ID3D12StateObject *rt_pso;
ID3D12Device *device;
ID3D12Resource *srv;
ID3D12Resource *uav;
ID3D12Resource *sbt;
if (!init_raytracing_test_context(&context, D3D12_RAYTRACING_TIER_1_0))
return;
device = context.context.device;
command_list = context.context.list;
command_list4 = context.list4;
init_test_geometry(device, &test_geom);
init_rt_geometry(&context, &test_rtases, &test_geom,
2, 10.0f, 2, 1.0f, 10.0f, 0);
/* Global root signature */
{
D3D12_ROOT_PARAMETER root_param[1];
D3D12_ROOT_SIGNATURE_DESC rs_desc;
D3D12_DESCRIPTOR_RANGE ranges[2];
memset(&rs_desc, 0, sizeof(rs_desc));
memset(root_param, 0, sizeof(root_param));
memset(ranges, 0, sizeof(ranges));
rs_desc.NumParameters = ARRAY_SIZE(root_param);
rs_desc.pParameters = root_param;
root_param[0].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
root_param[0].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
root_param[0].DescriptorTable.NumDescriptorRanges = ARRAY_SIZE(ranges);
root_param[0].DescriptorTable.pDescriptorRanges = ranges;
ranges[0].NumDescriptors = 2;
ranges[0].RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV;
ranges[0].OffsetInDescriptorsFromTableStart = 0;
ranges[1].NumDescriptors = 1;
ranges[1].RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_UAV;
ranges[1].OffsetInDescriptorsFromTableStart = 2;
create_root_signature(device, &rs_desc, &global_rs);
}
/* Local root signatures. */
{
D3D12_STATIC_SAMPLER_DESC sampler_descs[2];
D3D12_ROOT_SIGNATURE_DESC rs_desc;
memset(&rs_desc, 0, sizeof(rs_desc));
memset(sampler_descs, 0, sizeof(sampler_descs));
rs_desc.NumStaticSamplers = ARRAY_SIZE(sampler_descs);
rs_desc.pStaticSamplers = sampler_descs;
rs_desc.Flags = D3D12_ROOT_SIGNATURE_FLAG_LOCAL_ROOT_SIGNATURE;
/* First closesthit shader reads s0 and s2. Second one reads s1 and s2. s2 is shared, and must be defined
* equal across the PSO. */
sampler_descs[0].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
sampler_descs[0].AddressU = D3D12_TEXTURE_ADDRESS_MODE_CLAMP;
sampler_descs[0].AddressV = D3D12_TEXTURE_ADDRESS_MODE_CLAMP;
sampler_descs[0].AddressW = D3D12_TEXTURE_ADDRESS_MODE_CLAMP;
sampler_descs[0].Filter = D3D12_FILTER_MIN_MAG_MIP_POINT;
sampler_descs[0].ShaderRegister = 0;
sampler_descs[1] = sampler_descs[0];
sampler_descs[1].ShaderRegister = 2;
sampler_descs[1].AddressV = D3D12_TEXTURE_ADDRESS_MODE_WRAP;
create_root_signature(device, &rs_desc, &local_rs[0]);
sampler_descs[0].ShaderRegister = 1;
sampler_descs[0].AddressU = D3D12_TEXTURE_ADDRESS_MODE_WRAP;
sampler_descs[0].AddressV = D3D12_TEXTURE_ADDRESS_MODE_WRAP;
sampler_descs[0].AddressW = D3D12_TEXTURE_ADDRESS_MODE_WRAP;
create_root_signature(device, &rs_desc, &local_rs[1]);
}
/* Create PSO. */
{
D3D12_HIT_GROUP_DESC hit_group[2];
struct rt_pso_factory factory;
unsigned local_index[2];
rt_pso_factory_init(&factory);
rt_pso_factory_add_dxil_library(&factory, get_static_sampler_rt_lib(), 0, NULL);
rt_pso_factory_add_state_object_config(&factory, D3D12_STATE_OBJECT_FLAG_NONE);
rt_pso_factory_add_pipeline_config(&factory, 1);
rt_pso_factory_add_shader_config(&factory, 8, 4);
rt_pso_factory_add_global_root_signature(&factory, global_rs);
local_index[0] = rt_pso_factory_add_local_root_signature(&factory, local_rs[0]);
local_index[1] = rt_pso_factory_add_local_root_signature(&factory, local_rs[1]);
memset(hit_group, 0, sizeof(hit_group));
hit_group[0].Type = D3D12_HIT_GROUP_TYPE_TRIANGLES;
hit_group[0].HitGroupExport = u"RayHit1";
hit_group[0].ClosestHitShaderImport = u"RayClosest1";
hit_group[1].Type = D3D12_HIT_GROUP_TYPE_TRIANGLES;
hit_group[1].HitGroupExport = u"RayHit2";
hit_group[1].ClosestHitShaderImport = u"RayClosest2";
rt_pso_factory_add_hit_group(&factory, &hit_group[0]);
rt_pso_factory_add_hit_group(&factory, &hit_group[1]);
rt_pso_factory_add_subobject_to_exports_association(&factory, local_index[0],
1, &hit_group[0].HitGroupExport);
rt_pso_factory_add_subobject_to_exports_association(&factory, local_index[1],
1, &hit_group[1].HitGroupExport);
rt_pso = rt_pso_factory_compile(&context, &factory, D3D12_STATE_OBJECT_TYPE_RAYTRACING_PIPELINE);
}
if (rt_pso)
{
uint8_t sbt_data[D3D12_RAYTRACING_SHADER_TABLE_BYTE_ALIGNMENT * 6];
const void *hit1, *hit2, *gen, *miss;
ID3D12StateObjectProperties *props;
ID3D12StateObject_QueryInterface(rt_pso, &IID_ID3D12StateObjectProperties, (void**)&props);
hit1 = ID3D12StateObjectProperties_GetShaderIdentifier(props, u"RayHit1");
hit2 = ID3D12StateObjectProperties_GetShaderIdentifier(props, u"RayHit2");
gen = ID3D12StateObjectProperties_GetShaderIdentifier(props, u"RayGen");
miss = ID3D12StateObjectProperties_GetShaderIdentifier(props, u"RayMiss");
memcpy(sbt_data + D3D12_RAYTRACING_SHADER_TABLE_BYTE_ALIGNMENT * 0, gen, D3D12_SHADER_IDENTIFIER_SIZE_IN_BYTES);
memcpy(sbt_data + D3D12_RAYTRACING_SHADER_TABLE_BYTE_ALIGNMENT * 1, miss, D3D12_SHADER_IDENTIFIER_SIZE_IN_BYTES);
/* Hit SBTs for 2x2 quads. */
memcpy(sbt_data + D3D12_RAYTRACING_SHADER_TABLE_BYTE_ALIGNMENT * 2, hit1, D3D12_SHADER_IDENTIFIER_SIZE_IN_BYTES);
memcpy(sbt_data + D3D12_RAYTRACING_SHADER_TABLE_BYTE_ALIGNMENT * 3, hit2, D3D12_SHADER_IDENTIFIER_SIZE_IN_BYTES);
memcpy(sbt_data + D3D12_RAYTRACING_SHADER_TABLE_BYTE_ALIGNMENT * 4, hit2, D3D12_SHADER_IDENTIFIER_SIZE_IN_BYTES);
memcpy(sbt_data + D3D12_RAYTRACING_SHADER_TABLE_BYTE_ALIGNMENT * 5, hit1, D3D12_SHADER_IDENTIFIER_SIZE_IN_BYTES);
ID3D12StateObjectProperties_Release(props);
sbt = create_upload_buffer(device, sizeof(sbt_data), sbt_data);
}
else
sbt = NULL;
srv = create_default_texture2d(device, 2, 2, 1, 1,
DXGI_FORMAT_R32_FLOAT, D3D12_RESOURCE_FLAG_NONE, D3D12_RESOURCE_STATE_COPY_DEST);
uav = create_default_buffer(device, 4 * sizeof(float),
D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
{
const float data[] = { 10.0f, 20.0f, 30.0f, 40.0f };
D3D12_SUBRESOURCE_DATA srv_data;
srv_data.pData = data;
srv_data.RowPitch = 2 * sizeof(float);
srv_data.SlicePitch = 4 * sizeof(float);
upload_texture_data(srv, &srv_data, 1, context.context.queue, command_list);
reset_command_list(command_list, context.context.allocator);
}
heap = create_gpu_descriptor_heap(device, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, 3);
{
D3D12_SHADER_RESOURCE_VIEW_DESC srv_desc;
D3D12_CPU_DESCRIPTOR_HANDLE h;
memset(&srv_desc, 0, sizeof(srv_desc));
srv_desc.ViewDimension = D3D12_SRV_DIMENSION_RAYTRACING_ACCELERATION_STRUCTURE;
srv_desc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
srv_desc.RaytracingAccelerationStructure.Location =
ID3D12Resource_GetGPUVirtualAddress(test_rtases.top_acceleration_structures[0]);
h = ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(heap);
ID3D12Device_CreateShaderResourceView(device, NULL, &srv_desc, h);
}
{
D3D12_SHADER_RESOURCE_VIEW_DESC srv_desc;
D3D12_CPU_DESCRIPTOR_HANDLE h;
memset(&srv_desc, 0, sizeof(srv_desc));
srv_desc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D;
srv_desc.Format = DXGI_FORMAT_R32_FLOAT;
srv_desc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
srv_desc.Texture2D.MipLevels = 1;
h = ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(heap);
h.ptr += ID3D12Device_GetDescriptorHandleIncrementSize(device, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
ID3D12Device_CreateShaderResourceView(device, srv, &srv_desc, h);
}
{
D3D12_UNORDERED_ACCESS_VIEW_DESC uav_desc;
D3D12_CPU_DESCRIPTOR_HANDLE h;
memset(&uav_desc, 0, sizeof(uav_desc));
uav_desc.ViewDimension = D3D12_UAV_DIMENSION_BUFFER;
uav_desc.Format = DXGI_FORMAT_UNKNOWN;
uav_desc.Buffer.NumElements = 4;
uav_desc.Buffer.StructureByteStride = 4;
h = ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(heap);
h.ptr += 2 * ID3D12Device_GetDescriptorHandleIncrementSize(device, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
ID3D12Device_CreateUnorderedAccessView(device, uav, NULL, &uav_desc, h);
}
ID3D12GraphicsCommandList4_SetComputeRootSignature(command_list4, global_rs);
ID3D12GraphicsCommandList4_SetPipelineState1(command_list4, rt_pso);
ID3D12GraphicsCommandList4_SetDescriptorHeaps(command_list4, 1, &heap);
ID3D12GraphicsCommandList4_SetComputeRootDescriptorTable(command_list4, 0,
ID3D12DescriptorHeap_GetGPUDescriptorHandleForHeapStart(heap));
if (rt_pso)
{
D3D12_DISPATCH_RAYS_DESC ray_desc;
memset(&ray_desc, 0, sizeof(ray_desc));
ray_desc.Width = 2;
ray_desc.Height = 2;
ray_desc.Depth = 1;
ray_desc.RayGenerationShaderRecord.StartAddress =
ID3D12Resource_GetGPUVirtualAddress(sbt) + 0 * D3D12_RAYTRACING_SHADER_TABLE_BYTE_ALIGNMENT;
ray_desc.RayGenerationShaderRecord.SizeInBytes = D3D12_RAYTRACING_SHADER_TABLE_BYTE_ALIGNMENT;
ray_desc.MissShaderTable.StartAddress =
ID3D12Resource_GetGPUVirtualAddress(sbt) + 1 * D3D12_RAYTRACING_SHADER_TABLE_BYTE_ALIGNMENT;
ray_desc.MissShaderTable.SizeInBytes = D3D12_RAYTRACING_SHADER_TABLE_BYTE_ALIGNMENT;
ray_desc.MissShaderTable.StrideInBytes = D3D12_RAYTRACING_SHADER_TABLE_BYTE_ALIGNMENT;
ray_desc.HitGroupTable.StartAddress =
ID3D12Resource_GetGPUVirtualAddress(sbt) + 2 * D3D12_RAYTRACING_SHADER_TABLE_BYTE_ALIGNMENT;
ray_desc.HitGroupTable.SizeInBytes = 4 * D3D12_RAYTRACING_SHADER_TABLE_BYTE_ALIGNMENT;
ray_desc.HitGroupTable.StrideInBytes = D3D12_RAYTRACING_SHADER_TABLE_BYTE_ALIGNMENT;
ID3D12GraphicsCommandList4_DispatchRays(command_list4, &ray_desc);
}
transition_resource_state(command_list, uav, D3D12_RESOURCE_STATE_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_SOURCE);
get_buffer_readback_with_command_list(uav, DXGI_FORMAT_R32_FLOAT, &rb, context.context.queue, command_list);
{
static const float expected[] = { 60.0f, 30.0f, 30.0f, 60.0f };
unsigned int i;
for (i = 0; i < 4; i++)
{
ok(expected[i] == get_readback_float(&rb, i, 0), "Sampled value #%u: %f != reference %f\n",
i, get_readback_float(&rb, i, 0), expected[i]);
}
}
release_resource_readback(&rb);
ID3D12Resource_Release(srv);
ID3D12Resource_Release(uav);
if (sbt)
ID3D12Resource_Release(sbt);
ID3D12DescriptorHeap_Release(heap);
destroy_test_geometry(&test_geom);
destroy_rt_geometry(&test_rtases);
ID3D12RootSignature_Release(local_rs[0]);
ID3D12RootSignature_Release(local_rs[1]);
ID3D12RootSignature_Release(global_rs);
if (rt_pso)
ID3D12StateObject_Release(rt_pso);
destroy_raytracing_test_context(&context);
}