From 0958d8e1863f0f9d357ebc6058133025d8f090ba Mon Sep 17 00:00:00 2001 From: FakeMichau <49685661+FakeMichau@users.noreply.github.com> Date: Tue, 20 Oct 2026 12:25:07 +0200 Subject: [PATCH] Replace FSR4's autoexposure with our own Slopped. Just moves the autoexposure to our side. Mainly fixes DLSS inputs in UE games where the input color resource might be oversized. Compared to the previous workaround, this doesn't create resource copies and works with dynamic res. Closes #1227 --- OptiScaler/OptiScaler.vcxproj | 4 + OptiScaler/OptiScaler.vcxproj.filters | 12 + OptiScaler/shaders/auto_exposure/AE_Common.h | 122 ++++++++ OptiScaler/shaders/auto_exposure/AE_Dx12.cpp | 215 ++++++++++++++ OptiScaler/shaders/auto_exposure/AE_Dx12.h | 49 ++++ .../shaders/auto_exposure/precompile/AE.hlsl | 116 ++++++++ .../auto_exposure/precompile/AE_Shader.cso | Bin 0 -> 5044 bytes .../auto_exposure/precompile/AE_Shader.h | 270 ++++++++++++++++++ OptiScaler/upscalers/ffx/FFXFeature_Dx12.cpp | 155 +++------- OptiScaler/upscalers/ffx/FFXFeature_Dx12.h | 7 +- 10 files changed, 828 insertions(+), 122 deletions(-) create mode 100644 OptiScaler/shaders/auto_exposure/AE_Common.h create mode 100644 OptiScaler/shaders/auto_exposure/AE_Dx12.cpp create mode 100644 OptiScaler/shaders/auto_exposure/AE_Dx12.h create mode 100644 OptiScaler/shaders/auto_exposure/precompile/AE.hlsl create mode 100644 OptiScaler/shaders/auto_exposure/precompile/AE_Shader.cso create mode 100644 OptiScaler/shaders/auto_exposure/precompile/AE_Shader.h diff --git a/OptiScaler/OptiScaler.vcxproj b/OptiScaler/OptiScaler.vcxproj index 5a36d05d..9de465cb 100644 --- a/OptiScaler/OptiScaler.vcxproj +++ b/OptiScaler/OptiScaler.vcxproj @@ -518,6 +518,9 @@ copy NUL "$(SolutionDir)x64\Release\a\!! EXTRACT ALL FILES TO GAME FOLDER !!" /Y + + + @@ -819,6 +822,7 @@ copy NUL "$(SolutionDir)x64\Release\a\!! EXTRACT ALL FILES TO GAME FOLDER !!" /Y + diff --git a/OptiScaler/OptiScaler.vcxproj.filters b/OptiScaler/OptiScaler.vcxproj.filters index 33b8a434..823faad9 100644 --- a/OptiScaler/OptiScaler.vcxproj.filters +++ b/OptiScaler/OptiScaler.vcxproj.filters @@ -188,6 +188,15 @@ Config + + Header Files + + + Header Files + + + Header Files + Header Files @@ -1280,6 +1289,9 @@ Source Files + + Source Files + Source Files diff --git a/OptiScaler/shaders/auto_exposure/AE_Common.h b/OptiScaler/shaders/auto_exposure/AE_Common.h new file mode 100644 index 00000000..95d90298 --- /dev/null +++ b/OptiScaler/shaders/auto_exposure/AE_Common.h @@ -0,0 +1,122 @@ +#pragma once + +#include "SysUtils.h" + +static std::string aeShader = R"( +// Auto exposure from the log average luminance of the renderSize part of color, same as FSR2. +// FSR3 clamps the log luma instead of the luma, which makes every pixel darker than 1 count as 1 +// and caps the exposure way too low for typical pre-exposed input. + +cbuffer Params : register(b0) +{ + uint2 RenderSize; + uint GroupCountX; + uint GroupCount; + float DeltaTime; // seconds + uint Reset; + uint PassIndex; + float PreExposure; +}; + +Texture2D Color : register(t0); +// [0] smoothed log luma carried between frames, [1..] per group log luma sums +RWStructuredBuffer Data : register(u0); +RWTexture2D Exposure : register(u1); + +#define THREADS 256 +#define TILE 32 + +static const float Epsilon = 6.10e-05f; +static const float Fp16Max = 65504.0f; + +groupshared float Shared[THREADS]; + +float LogLuma(uint2 pos) +{ + // Exposure is applied after FSR removes pre-exposure, so it has to be measured without it too + const float3 rgb = max(0.0f, Color.Load(int3(pos, 0)).rgb) / PreExposure; + const float luma = min(dot(rgb, float3(0.2126f, 0.7152f, 0.0722f)), Fp16Max); + return log(max(Epsilon, luma)); +} + +float GroupSum(float value, uint tid) +{ + Shared[tid] = value; + GroupMemoryBarrierWithGroupSync(); + + [unroll] + for (uint stride = THREADS / 2; stride > 0; stride >>= 1) + { + if (tid < stride) + Shared[tid] += Shared[tid + stride]; + + GroupMemoryBarrierWithGroupSync(); + } + + return Shared[0]; +} + +float ComputeAutoExposureFromLavg(float Lavg) +{ + Lavg = exp(Lavg); + + const float S = 100.0f; // ISO arithmetic speed + const float K = 12.5f; + const float ExposureISO100 = log2((Lavg * S) / K); + + const float q = 0.65f; + const float Lmax = (78.0f / (q * S)) * pow(2.0f, ExposureISO100); + + return 1.0f / Lmax; +} + +[numthreads(16, 16, 1)] +void CSMain(uint3 gid : SV_GroupID, uint3 gtid : SV_GroupThreadID, uint tid : SV_GroupIndex) +{ + if (PassIndex == 0) + { + float sum = 0.0f; + + [unroll] + for (uint y = 0; y < TILE; y += 16) + { + [unroll] + for (uint x = 0; x < TILE; x += 16) + { + const uint2 pos = gid.xy * TILE + gtid.xy + uint2(x, y); + + if (all(pos < RenderSize)) + sum += LogLuma(pos); + } + } + + const float total = GroupSum(sum, tid); + + if (tid == 0) + Data[1 + gid.y * GroupCountX + gid.x] = total; + } + else + { + float sum = 0.0f; + + for (uint i = tid; i < GroupCount; i += THREADS) + sum += Data[1 + i]; + + const float total = GroupSum(sum, tid); + + if (tid == 0) + { + float logLuma = total / (float(RenderSize.x) * float(RenderSize.y)); + + if (Reset == 0) + { + const float prevLogLuma = Data[0]; + logLuma = prevLogLuma + (logLuma - prevLogLuma) * (1.0f - exp(-DeltaTime)); + } + + Data[0] = logLuma; + Exposure[uint2(0, 0)] = ComputeAutoExposureFromLavg(logLuma); + } + } +} +)"; diff --git a/OptiScaler/shaders/auto_exposure/AE_Dx12.cpp b/OptiScaler/shaders/auto_exposure/AE_Dx12.cpp new file mode 100644 index 00000000..169df5dc --- /dev/null +++ b/OptiScaler/shaders/auto_exposure/AE_Dx12.cpp @@ -0,0 +1,215 @@ +#include "pch.h" +#include "AE_Dx12.h" + +#include "AE_Common.h" +#include "precompile/AE_Shader.h" + +#include + +using Microsoft::WRL::ComPtr; + +static constexpr uint32_t AE_THREADS = 256; +static constexpr uint32_t AE_TILE = 32; + +bool AE_Dx12::CreateRootSignature(ID3D12Device* InDevice) +{ + CD3DX12_DESCRIPTOR_RANGE1 ranges[2]; + ranges[0].Init(D3D12_DESCRIPTOR_RANGE_TYPE_SRV, 1, 0); + ranges[1].Init(D3D12_DESCRIPTOR_RANGE_TYPE_UAV, 2, 0); + + // Root constants, so every dispatch has its own values without a constant buffer per frame + CD3DX12_ROOT_PARAMETER1 rootParameters[2]; + rootParameters[0].InitAsConstants(sizeof(InternalConstants) / sizeof(uint32_t), 0); + rootParameters[1].InitAsDescriptorTable(_countof(ranges), ranges); + + CD3DX12_VERSIONED_ROOT_SIGNATURE_DESC rootSigDesc {}; + rootSigDesc.Init_1_1(_countof(rootParameters), rootParameters); + + ComPtr errorBlob; + ComPtr signatureBlob; + + auto hr = D3D12SerializeVersionedRootSignature(&rootSigDesc, &signatureBlob, &errorBlob); + + if (FAILED(hr)) + { + LOG_ERROR("[{0}] D3D12SerializeVersionedRootSignature error {1:x}", _name, hr); + return false; + } + + hr = InDevice->CreateRootSignature(0, signatureBlob->GetBufferPointer(), signatureBlob->GetBufferSize(), + IID_PPV_ARGS(&_rootSignature)); + + if (FAILED(hr)) + { + LOG_ERROR("[{0}] CreateRootSignature error {1:x}", _name, hr); + return false; + } + + return true; +} + +bool AE_Dx12::EnsureDataBuffer(uint32_t InElements) +{ + if (_data != nullptr && _dataElements >= InElements) + return true; + + // Previous frames can still be using it + DeferredRelease::Release(_data); + _dataElements = 0; + _historyValid = false; + + auto heapProps = CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT); + auto desc = CD3DX12_RESOURCE_DESC::Buffer(InElements * sizeof(float), D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS); + + auto hr = _device->CreateCommittedResource(&heapProps, D3D12_HEAP_FLAG_NONE, &desc, + D3D12_RESOURCE_STATE_UNORDERED_ACCESS, nullptr, IID_PPV_ARGS(&_data)); + + if (hr != S_OK) + { + LOG_ERROR("[{0}] CreateCommittedResource error {1:x}", _name, (unsigned int) hr); + return false; + } + + _data->SetName(L"AE_Data"); + _dataElements = InElements; + + return true; +} + +bool AE_Dx12::Dispatch(ID3D12GraphicsCommandList* InCmdList, ID3D12Resource* InColor, uint32_t InRenderWidth, + uint32_t InRenderHeight, float InPreExposure, float InDeltaTimeSeconds, bool InReset) +{ + if (!_init || _device == nullptr || InCmdList == nullptr || InColor == nullptr || InRenderWidth == 0 || + InRenderHeight == 0) + return false; + + LOG_DEBUG("[{0}] Start!", _name); + + const uint32_t groupCountX = (InRenderWidth + AE_TILE - 1) / AE_TILE; + const uint32_t groupCountY = (InRenderHeight + AE_TILE - 1) / AE_TILE; + const uint32_t groupCount = groupCountX * groupCountY; + + if (!EnsureDataBuffer(groupCount + 1)) + return false; + + ScopedGpuTime_Dx12 scopedGpuTime(GpuTime.get(), InCmdList); + + _counter++; + _counter = _counter % AE_NUM_OF_HEAPS; + FrameDescriptorHeap& currentHeap = _frameHeaps[_counter]; + + CreateShaderResourceView(_device, InColor, currentHeap.GetSrvCPU(0)); + + D3D12_UNORDERED_ACCESS_VIEW_DESC dataUav {}; + dataUav.Format = DXGI_FORMAT_UNKNOWN; + dataUav.ViewDimension = D3D12_UAV_DIMENSION_BUFFER; + dataUav.Buffer.NumElements = _dataElements; + dataUav.Buffer.StructureByteStride = sizeof(float); + _device->CreateUnorderedAccessView(_data, nullptr, &dataUav, currentHeap.GetUavCPU(0)); + + CreateUnorderedAccessView(_device, _exposure, currentHeap.GetUavCPU(1), 0); + + SetBufferState(InCmdList, D3D12_RESOURCE_STATE_UNORDERED_ACCESS, _exposure, &_exposureState); + + // Previous pass 1 may still be reading the sums + auto dataBarrier = CD3DX12_RESOURCE_BARRIER::UAV(_data); + InCmdList->ResourceBarrier(1, &dataBarrier); + + ID3D12DescriptorHeap* heaps[] = { currentHeap.GetHeapCSU() }; + InCmdList->SetDescriptorHeaps(_countof(heaps), heaps); + + InCmdList->SetComputeRootSignature(_rootSignature); + InCmdList->SetPipelineState(_pipelineState); + InCmdList->SetComputeRootDescriptorTable(1, currentHeap.GetTableGPUStart()); + + InternalConstants constants {}; + constants.RenderWidth = InRenderWidth; + constants.RenderHeight = InRenderHeight; + constants.GroupCountX = groupCountX; + constants.GroupCount = groupCount; + constants.DeltaTime = std::clamp(InDeltaTimeSeconds, 0.0f, 1.0f); + constants.PreExposure = InPreExposure > 0.0f ? InPreExposure : 1.0f; + // Without history the scene luma is taken as is instead of adapting from a stale value + constants.Reset = (InReset || !_historyValid) ? 1 : 0; + + // Per tile log luma sums + constants.PassIndex = 0; + InCmdList->SetComputeRoot32BitConstants(0, sizeof(constants) / sizeof(uint32_t), &constants, 0); + InCmdList->Dispatch(groupCountX, groupCountY, 1); + + InCmdList->ResourceBarrier(1, &dataBarrier); + + // Average, temporal adaptation and exposure + constants.PassIndex = 1; + InCmdList->SetComputeRoot32BitConstants(0, sizeof(constants) / sizeof(uint32_t), &constants, 0); + InCmdList->Dispatch(1, 1, 1); + + SetBufferState(InCmdList, D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE, _exposure, &_exposureState); + + _historyValid = true; + + return true; +} + +AE_Dx12::AE_Dx12(std::string InName, ID3D12Device* InDevice) : Shader_Dx12(InName, InDevice) +{ + if (InDevice == nullptr) + { + LOG_ERROR("InDevice is nullptr!"); + return; + } + + LOG_DEBUG("{0} start!", _name); + + if (!CreateRootSignature(InDevice)) + { + LOG_ERROR("Failed to create root signature"); + return; + } + + if (!CreateComputePipeline(InDevice, &_pipelineState, AE_cso, sizeof(AE_cso), aeShader.c_str())) + { + LOG_ERROR("[{0}] Failed to create compute pipeline", _name); + return; + } + + auto heapProps = CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT); + auto desc = CD3DX12_RESOURCE_DESC::Tex2D(DXGI_FORMAT_R32_FLOAT, 1, 1, 1, 1, 1, 0, + D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS); + + auto hr = InDevice->CreateCommittedResource(&heapProps, D3D12_HEAP_FLAG_NONE, &desc, _exposureState, nullptr, + IID_PPV_ARGS(&_exposure)); + + if (hr != S_OK) + { + LOG_ERROR("[{0}] CreateCommittedResource error {1:x}", _name, (unsigned int) hr); + return; + } + + _exposure->SetName(L"AE_Exposure"); + + ScopedSkipHeapCapture skipHeapCapture {}; + + for (int i = 0; i < AE_NUM_OF_HEAPS; i++) + { + if (!_frameHeaps[i].Initialize(InDevice, 1, 2, 0)) + { + LOG_ERROR("[{0}] Failed to init heap", _name); + return; + } + } + + _init = true; +} + +AE_Dx12::~AE_Dx12() +{ + if (State::Instance().isShuttingDown) + return; + + for (int i = 0; i < AE_NUM_OF_HEAPS; i++) + _frameHeaps[i].ReleaseHeaps(); + + DeferredRelease::Release(_data); + DeferredRelease::Release(_exposure); +} diff --git a/OptiScaler/shaders/auto_exposure/AE_Dx12.h b/OptiScaler/shaders/auto_exposure/AE_Dx12.h new file mode 100644 index 00000000..13a3d40f --- /dev/null +++ b/OptiScaler/shaders/auto_exposure/AE_Dx12.h @@ -0,0 +1,49 @@ +#pragma once +#include +#include +#include +#include + +#define AE_NUM_OF_HEAPS 2 + +// Computes an FSR2 style auto exposure from the renderSize part of color into a 1x1 R32_FLOAT texture +class AE_Dx12 : public Shader_Dx12 +{ + private: + struct InternalConstants + { + uint32_t RenderWidth; + uint32_t RenderHeight; + uint32_t GroupCountX; + uint32_t GroupCount; + float DeltaTime; + uint32_t Reset; + uint32_t PassIndex; + float PreExposure; + }; + + FrameDescriptorHeap _frameHeaps[AE_NUM_OF_HEAPS]; + + // [0] smoothed log luma, [1..] per group sums + ID3D12Resource* _data = nullptr; + uint32_t _dataElements = 0; + + ID3D12Resource* _exposure = nullptr; + D3D12_RESOURCE_STATES _exposureState = D3D12_RESOURCE_STATE_UNORDERED_ACCESS; + + bool _historyValid = false; + + bool CreateRootSignature(ID3D12Device* InDevice); + bool EnsureDataBuffer(uint32_t InElements); + + public: + // Leaves Exposure() in NON_PIXEL_SHADER_RESOURCE + bool Dispatch(ID3D12GraphicsCommandList* InCmdList, ID3D12Resource* InColor, uint32_t InRenderWidth, + uint32_t InRenderHeight, float InPreExposure, float InDeltaTimeSeconds, bool InReset); + + ID3D12Resource* Exposure() { return _exposure; } + + AE_Dx12(std::string InName, ID3D12Device* InDevice); + + ~AE_Dx12(); +}; diff --git a/OptiScaler/shaders/auto_exposure/precompile/AE.hlsl b/OptiScaler/shaders/auto_exposure/precompile/AE.hlsl new file mode 100644 index 00000000..94a9a35f --- /dev/null +++ b/OptiScaler/shaders/auto_exposure/precompile/AE.hlsl @@ -0,0 +1,116 @@ +// Auto exposure from the log average luminance of the renderSize part of color, same as FSR2. +// FSR3 clamps the log luma instead of the luma, which makes every pixel darker than 1 count as 1 +// and caps the exposure way too low for typical pre-exposed input. + +cbuffer Params : register(b0) +{ + uint2 RenderSize; + uint GroupCountX; + uint GroupCount; + float DeltaTime; // seconds + uint Reset; + uint PassIndex; + float PreExposure; +}; + +Texture2D Color : register(t0); +// [0] smoothed log luma carried between frames, [1..] per group log luma sums +RWStructuredBuffer Data : register(u0); +RWTexture2D Exposure : register(u1); + +#define THREADS 256 +#define TILE 32 + +static const float Epsilon = 6.10e-05f; +static const float Fp16Max = 65504.0f; + +groupshared float Shared[THREADS]; + +float LogLuma(uint2 pos) +{ + // Exposure is applied after FSR removes pre-exposure, so it has to be measured without it too + const float3 rgb = max(0.0f, Color.Load(int3(pos, 0)).rgb) / PreExposure; + const float luma = min(dot(rgb, float3(0.2126f, 0.7152f, 0.0722f)), Fp16Max); + return log(max(Epsilon, luma)); +} + +float GroupSum(float value, uint tid) +{ + Shared[tid] = value; + GroupMemoryBarrierWithGroupSync(); + + [unroll] + for (uint stride = THREADS / 2; stride > 0; stride >>= 1) + { + if (tid < stride) + Shared[tid] += Shared[tid + stride]; + + GroupMemoryBarrierWithGroupSync(); + } + + return Shared[0]; +} + +float ComputeAutoExposureFromLavg(float Lavg) +{ + Lavg = exp(Lavg); + + const float S = 100.0f; // ISO arithmetic speed + const float K = 12.5f; + const float ExposureISO100 = log2((Lavg * S) / K); + + const float q = 0.65f; + const float Lmax = (78.0f / (q * S)) * pow(2.0f, ExposureISO100); + + return 1.0f / Lmax; +} + +[numthreads(16, 16, 1)] +void CSMain(uint3 gid : SV_GroupID, uint3 gtid : SV_GroupThreadID, uint tid : SV_GroupIndex) +{ + if (PassIndex == 0) + { + float sum = 0.0f; + + [unroll] + for (uint y = 0; y < TILE; y += 16) + { + [unroll] + for (uint x = 0; x < TILE; x += 16) + { + const uint2 pos = gid.xy * TILE + gtid.xy + uint2(x, y); + + if (all(pos < RenderSize)) + sum += LogLuma(pos); + } + } + + const float total = GroupSum(sum, tid); + + if (tid == 0) + Data[1 + gid.y * GroupCountX + gid.x] = total; + } + else + { + float sum = 0.0f; + + for (uint i = tid; i < GroupCount; i += THREADS) + sum += Data[1 + i]; + + const float total = GroupSum(sum, tid); + + if (tid == 0) + { + float logLuma = total / (float(RenderSize.x) * float(RenderSize.y)); + + if (Reset == 0) + { + const float prevLogLuma = Data[0]; + logLuma = prevLogLuma + (logLuma - prevLogLuma) * (1.0f - exp(-DeltaTime)); + } + + Data[0] = logLuma; + Exposure[uint2(0, 0)] = ComputeAutoExposureFromLavg(logLuma); + } + } +} diff --git a/OptiScaler/shaders/auto_exposure/precompile/AE_Shader.cso b/OptiScaler/shaders/auto_exposure/precompile/AE_Shader.cso new file mode 100644 index 0000000000000000000000000000000000000000..5f0c3efa115891b6dcff08e0bcdb2d118f19b289 GIT binary patch literal 5044 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 literal 0 HcmV?d00001 diff --git a/OptiScaler/shaders/auto_exposure/precompile/AE_Shader.h b/OptiScaler/shaders/auto_exposure/precompile/AE_Shader.h new file mode 100644 index 00000000..a3e8855c --- /dev/null +++ b/OptiScaler/shaders/auto_exposure/precompile/AE_Shader.h @@ -0,0 +1,270 @@ +#pragma once + +inline static const unsigned char AE_cso[] = { + 0x44, 0x58, 0x42, 0x43, 0xd2, 0x6a, 0x7a, 0xda, 0xbb, 0xd6, 0x4d, 0xc4, 0xb8, 0x47, 0xc3, 0x30, 0x1f, 0x66, 0xb0, + 0x6d, 0x01, 0x00, 0x00, 0x00, 0xb4, 0x13, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x48, 0x00, + 0x00, 0x00, 0x58, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0x20, 0x01, 0x00, 0x00, 0x3c, 0x01, 0x00, 0x00, 0x53, + 0x46, 0x49, 0x30, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 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, 0xb0, 0x00, 0x00, 0x00, 0x34, 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, + 0x10, 0x00, 0x00, 0x00, 0x10, 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, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 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, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x43, 0x53, 0x4d, 0x61, 0x69, 0x6e, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x48, 0x41, 0x53, 0x48, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc2, 0x0c, 0x61, 0x0f, + 0xc3, 0xec, 0x9f, 0x9f, 0x6a, 0x57, 0x95, 0xca, 0xfe, 0x32, 0x60, 0xf8, 0x44, 0x58, 0x49, 0x4c, 0x70, 0x12, 0x00, + 0x00, 0x60, 0x00, 0x05, 0x00, 0x9c, 0x04, 0x00, 0x00, 0x44, 0x58, 0x49, 0x4c, 0x00, 0x01, 0x00, 0x00, 0x10, 0x00, + 0x00, 0x00, 0x58, 0x12, 0x00, 0x00, 0x42, 0x43, 0xc0, 0xde, 0x21, 0x0c, 0x00, 0x00, 0x93, 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, 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, 0x0b, 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, 0x36, 0x18, 0xc4, 0xff, 0xff, 0xff, 0xff, + 0x0f, 0x00, 0x03, 0x48, 0x00, 0x00, 0x49, 0x18, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x13, 0x82, 0x60, 0x42, 0x20, + 0x4c, 0x08, 0x86, 0x09, 0x01, 0x01, 0x00, 0x89, 0x20, 0x00, 0x00, 0x78, 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, 0xdc, 0xc1, 0x0c, 0x40, 0x02, 0x0a, 0x00, 0x83, 0x08, 0xc1, 0x30, 0x02, 0x50, + 0x82, 0x81, 0x88, 0x39, 0x02, 0x30, 0x28, 0x83, 0x61, 0x18, 0x74, 0x14, 0xc1, 0x30, 0x28, 0x29, 0x03, 0x60, 0x00, + 0xb4, 0xcc, 0x11, 0x20, 0xd4, 0xdc, 0x33, 0x5c, 0xfe, 0x84, 0x3d, 0x84, 0xe4, 0x87, 0x40, 0x33, 0x2c, 0x04, 0x0a, + 0x9c, 0xb2, 0x0c, 0xc6, 0x63, 0x18, 0x06, 0x00, 0x00, 0x40, 0x43, 0x50, 0x21, 0x00, 0x03, 0x00, 0x48, 0xba, 0x69, + 0xb8, 0xfc, 0x09, 0x7b, 0x08, 0xc9, 0x5f, 0x09, 0x69, 0x25, 0x26, 0xbf, 0xb8, 0x6d, 0x54, 0x00, 0x00, 0x00, 0x18, + 0x45, 0xa1, 0x8c, 0xc7, 0x30, 0x0c, 0xc3, 0x30, 0x0c, 0xaa, 0x0a, 0x02, 0x18, 0x00, 0x00, 0x00, 0x00, 0x40, 0x57, + 0x19, 0x06, 0xc3, 0xa0, 0xec, 0xa8, 0xe1, 0xf2, 0x27, 0xec, 0x21, 0x24, 0x9f, 0xdb, 0xa8, 0x62, 0x25, 0x26, 0xbf, + 0xb8, 0x6d, 0x44, 0x00, 0x00, 0x00, 0x14, 0x62, 0x33, 0x1e, 0x83, 0xb8, 0xa3, 0x86, 0xcb, 0x9f, 0xb0, 0x87, 0x90, + 0x7c, 0x6e, 0xa3, 0x8a, 0x95, 0x98, 0x7c, 0xe4, 0xb6, 0x11, 0x61, 0x18, 0x86, 0x51, 0x08, 0xcf, 0x78, 0x0c, 0xfa, + 0xe6, 0x08, 0x82, 0x62, 0x3c, 0x46, 0x63, 0x18, 0x21, 0x89, 0x45, 0x19, 0x8c, 0xc7, 0x30, 0x00, 0x00, 0x00, 0x1a, + 0x22, 0x4b, 0x41, 0x19, 0x8f, 0x61, 0x90, 0x39, 0x10, 0x30, 0x8c, 0x40, 0x00, 0x33, 0xb5, 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, 0x3d, 0x94, 0xc3, 0x38, 0xd0, 0xc3, 0x3b, 0xc8, 0x03, 0x1f, 0x98, 0x03, 0x3b, 0xbc, 0x43, 0x38, 0xd0, + 0x03, 0x1b, 0x80, 0x01, 0x1d, 0xf8, 0x01, 0x18, 0xf8, 0x81, 0x1e, 0xe8, 0x41, 0x3b, 0xa4, 0x03, 0x3c, 0xcc, 0xc3, + 0x2f, 0xd0, 0x43, 0x3e, 0xc0, 0x43, 0x39, 0xa0, 0xc0, 0x98, 0x49, 0x0c, 0xc6, 0x81, 0x1d, 0xc2, 0x61, 0x1e, 0xe6, + 0xc1, 0x0d, 0x68, 0xa1, 0x1c, 0xf0, 0x81, 0x1e, 0xea, 0x41, 0x1e, 0xca, 0x41, 0x0e, 0x48, 0x81, 0x0f, 0xec, 0xa1, + 0x1c, 0xc6, 0x81, 0x1e, 0xde, 0x41, 0x1e, 0xf8, 0xc0, 0x1c, 0xd8, 0xe1, 0x1d, 0xc2, 0x81, 0x1e, 0xd8, 0x00, 0x0c, + 0xe8, 0xc0, 0x0f, 0xc0, 0xc0, 0x0f, 0x90, 0x90, 0xaa, 0xb4, 0xce, 0xf4, 0x8d, 0x03, 0x3b, 0x84, 0xc3, 0x3c, 0xcc, + 0x83, 0x1b, 0xc8, 0xc2, 0x2d, 0xcc, 0x02, 0x3d, 0xc8, 0x43, 0x3d, 0x8c, 0x03, 0x3d, 0xd4, 0x83, 0x3c, 0x94, 0x03, + 0x39, 0x88, 0x42, 0x3d, 0x98, 0x83, 0x39, 0x94, 0x83, 0x3c, 0xf0, 0x81, 0x39, 0xb0, 0xc3, 0x3b, 0x84, 0x03, 0x3d, + 0xf8, 0x01, 0x0a, 0x00, 0x6a, 0x67, 0xc2, 0xc6, 0x81, 0x1d, 0xc2, 0x61, 0x1e, 0xe6, 0xc1, 0x0d, 0x64, 0xe1, 0x16, + 0x68, 0xa1, 0x1c, 0xf0, 0x81, 0x1e, 0xea, 0x41, 0x1e, 0xca, 0x41, 0x0e, 0x48, 0x81, 0x0f, 0xcc, 0x81, 0x1d, 0xde, + 0x21, 0x1c, 0xe8, 0xc1, 0x0f, 0x50, 0x00, 0xd0, 0x3b, 0x8c, 0x20, 0x18, 0x67, 0xa4, 0x40, 0x04, 0x30, 0x12, 0x3a, + 0x62, 0xc3, 0x00, 0x0c, 0x03, 0x20, 0x79, 0x8e, 0x00, 0x14, 0xa6, 0x00, 0x06, 0x11, 0x80, 0x01, 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, 0x3a, 0x0f, 0x24, 0x90, 0x21, 0x23, 0x45, 0x44, 0x00, 0x76, 0x00, 0xf0, 0x90, + 0x87, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x21, 0xcf, 0x01, 0x04, 0x40, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43, 0x9e, 0x03, 0x08, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x86, 0x3c, 0x09, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x79, 0x16, 0x20, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xf2, 0x40, 0x40, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x30, 0xe4, 0x91, 0x80, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0xc8, 0x53, 0x01, 0x01, + 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x90, 0xe7, 0x02, 0x02, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x80, 0x21, 0x4f, 0x06, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43, 0x1e, 0x0e, + 0x08, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86, 0x3c, 0x1f, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0c, 0x79, 0xc4, 0x00, 0x08, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86, + 0x3c, 0x64, 0x00, 0x04, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43, 0x1e, 0x33, 0x00, 0x02, 0x60, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x2c, 0x10, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x32, 0x1e, 0x98, 0x18, + 0x19, 0x11, 0x4c, 0x90, 0x8c, 0x09, 0x26, 0x47, 0xc6, 0x04, 0x43, 0x32, 0x4a, 0x60, 0x04, 0xa0, 0x24, 0x8a, 0xa1, + 0x08, 0x0a, 0xa3, 0x10, 0x0a, 0xa8, 0x40, 0x28, 0x1c, 0x01, 0x20, 0x7a, 0x04, 0xa0, 0x40, 0x08, 0x9e, 0x01, 0xa0, + 0x79, 0x06, 0x80, 0xdc, 0x19, 0x00, 0x62, 0x67, 0x00, 0x00, 0x79, 0x18, 0x00, 0x00, 0x5a, 0x00, 0x00, 0x00, 0x1a, + 0x03, 0x4c, 0x90, 0x46, 0x02, 0x13, 0x44, 0x8f, 0x0c, 0x6f, 0xec, 0xed, 0x4d, 0x0c, 0x24, 0xc6, 0x25, 0xc7, 0x45, + 0xc6, 0x06, 0x46, 0xc6, 0x25, 0xe6, 0x06, 0x04, 0x45, 0x26, 0x86, 0x4c, 0x06, 0xc7, 0xec, 0x46, 0xe6, 0x26, 0x65, + 0x43, 0x10, 0x4c, 0x10, 0x0c, 0x68, 0x82, 0x60, 0x44, 0x1b, 0x84, 0x81, 0x98, 0x20, 0x18, 0xd2, 0x06, 0x61, 0x30, + 0x28, 0x8c, 0xcd, 0x4d, 0x10, 0x8c, 0x69, 0xc3, 0x80, 0x24, 0xc4, 0x04, 0x81, 0x0d, 0x3e, 0x02, 0x13, 0x04, 0x83, + 0xda, 0x20, 0x10, 0xc6, 0x86, 0x84, 0x58, 0x18, 0x82, 0x18, 0x1a, 0xc2, 0xd9, 0x10, 0x3c, 0x13, 0x04, 0x37, 0xf0, + 0x26, 0x08, 0x46, 0x35, 0x41, 0x08, 0x83, 0x6c, 0x82, 0x60, 0x58, 0x1b, 0x84, 0x81, 0xda, 0xb0, 0x10, 0x11, 0x43, + 0x10, 0x83, 0x34, 0x4d, 0x53, 0x35, 0x41, 0x80, 0x03, 0x6e, 0xc3, 0x32, 0x5c, 0x0c, 0x31, 0x0c, 0xcd, 0x34, 0x4d, + 0xce, 0x06, 0xc1, 0xc2, 0x26, 0x08, 0x73, 0xd0, 0x4d, 0x10, 0x8c, 0x6b, 0x03, 0x42, 0x68, 0x0c, 0x41, 0x0c, 0x1b, + 0xb0, 0x21, 0xe0, 0x36, 0x10, 0x50, 0xd6, 0x01, 0x13, 0x84, 0x22, 0xa0, 0x31, 0x34, 0xd5, 0x14, 0x96, 0xe6, 0x36, + 0x41, 0xa0, 0x83, 0x6d, 0x82, 0x60, 0x60, 0x1b, 0x06, 0x31, 0x10, 0x83, 0x61, 0x03, 0x41, 0x84, 0x01, 0x35, 0x06, + 0x1b, 0x8a, 0x0f, 0x0c, 0x00, 0x8f, 0x0c, 0x58, 0x98, 0xb1, 0xbd, 0x85, 0xd1, 0xf1, 0x79, 0x6b, 0x73, 0x4b, 0x83, + 0x7b, 0xa3, 0x2b, 0x73, 0xa3, 0x03, 0x19, 0x43, 0x0b, 0x93, 0x63, 0x34, 0x95, 0xd6, 0x06, 0xc7, 0x56, 0x06, 0x32, + 0xf4, 0x32, 0xb4, 0xb2, 0x02, 0x42, 0x25, 0x14, 0x14, 0xb4, 0x21, 0x40, 0x83, 0x09, 0x02, 0x1d, 0x68, 0x1b, 0x86, + 0x33, 0x48, 0x03, 0x35, 0xd8, 0x30, 0x98, 0xc1, 0x1a, 0xa8, 0xc1, 0x86, 0x81, 0x0d, 0xd8, 0x40, 0x0d, 0xaa, 0xb0, + 0xb1, 0xd9, 0xb5, 0xb9, 0xa4, 0x91, 0x95, 0xb9, 0xd1, 0x4d, 0x09, 0x82, 0x2a, 0x64, 0x78, 0x2e, 0x76, 0x65, 0x72, + 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x02, 0xa2, 0x09, 0x19, 0x9e, 0x8b, 0x5d, 0x18, 0x9b, 0x5d, 0x99, 0xdc, 0x94, 0xc0, + 0xa8, 0x43, 0x86, 0xe7, 0x32, 0x87, 0x16, 0x46, 0x56, 0x26, 0xd7, 0xf4, 0x46, 0x56, 0xc6, 0x36, 0x25, 0x48, 0xca, + 0x90, 0xe1, 0xb9, 0xc8, 0x95, 0xcd, 0xbd, 0xd5, 0xc9, 0x8d, 0x95, 0xcd, 0x4d, 0x09, 0xba, 0x3a, 0x64, 0x78, 0x2e, + 0x65, 0x6e, 0x74, 0x72, 0x79, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x53, 0x02, 0x32, 0x00, 0x00, 0x00, 0x79, 0x18, + 0x00, 0x00, 0x55, 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, 0xca, 0xc3, 0x0e, + 0xec, 0x60, 0x0f, 0xed, 0xe0, 0x06, 0xec, 0xf0, 0x0e, 0xef, 0x00, 0x0f, 0x33, 0x22, 0x88, 0x1c, 0xf0, 0xc1, 0x0d, + 0xc8, 0x41, 0x1c, 0xce, 0xc1, 0x0d, 0xec, 0x21, 0x1c, 0xe4, 0x81, 0x1d, 0xc2, 0x21, 0x1f, 0xde, 0xa1, 0x1e, 0xe8, + 0x61, 0x06, 0x13, 0x91, 0x03, 0x3e, 0xb8, 0x81, 0x38, 0xc8, 0x43, 0x39, 0x84, 0xc3, 0x3a, 0xb8, 0x81, 0x38, 0xc8, + 0x03, 0x00, 0x00, 0x00, 0x71, 0x20, 0x00, 0x00, 0x45, 0x00, 0x00, 0x00, 0x05, 0xf0, 0x04, 0x7e, 0x53, 0x74, 0x58, + 0x5e, 0x26, 0x03, 0x81, 0x33, 0x68, 0xb0, 0x19, 0xb4, 0x00, 0x83, 0x63, 0x4d, 0x00, 0x69, 0x4c, 0xa1, 0x19, 0x2e, + 0xdf, 0x79, 0xfc, 0x00, 0x88, 0x22, 0x84, 0x88, 0xec, 0x00, 0x1a, 0x2e, 0xdf, 0x79, 0xfc, 0x00, 0x69, 0x80, 0x08, + 0xf3, 0x8b, 0xdb, 0xb6, 0x07, 0x6a, 0xb8, 0x7c, 0xe7, 0xf1, 0x03, 0xaa, 0x28, 0x88, 0xa8, 0x74, 0x80, 0xc1, 0x2f, + 0x6e, 0xdb, 0x1c, 0xaa, 0xe1, 0xf2, 0x9d, 0xc7, 0x0f, 0xa8, 0xa2, 0x20, 0x22, 0x76, 0x72, 0x22, 0xc2, 0x2f, 0x6e, + 0xdb, 0x16, 0xb6, 0xe1, 0xf2, 0x9d, 0xc7, 0x17, 0x02, 0xaa, 0x28, 0x88, 0xa8, 0x74, 0x80, 0xa1, 0x24, 0x0c, 0x40, + 0xc0, 0xfc, 0xe2, 0xb6, 0x8d, 0x61, 0x1b, 0x2e, 0xdf, 0x79, 0x7c, 0x21, 0xa0, 0x8a, 0x82, 0x88, 0x4a, 0x07, 0x18, + 0x4a, 0xc2, 0x00, 0x04, 0xcc, 0x47, 0x6e, 0xdb, 0x1a, 0xa4, 0xe1, 0xf2, 0x9d, 0xc7, 0x17, 0x22, 0x02, 0x98, 0x88, + 0x10, 0x68, 0x86, 0x85, 0xb0, 0x04, 0x67, 0xb8, 0x7c, 0xe7, 0xf1, 0x07, 0x67, 0xba, 0xfd, 0xe2, 0xb6, 0x8d, 0x40, + 0x0c, 0x86, 0xcb, 0x77, 0x1e, 0xbf, 0x58, 0x80, 0x69, 0x22, 0x1a, 0x62, 0x68, 0x8f, 0x88, 0x00, 0x06, 0x71, 0x10, + 0x1b, 0x30, 0x72, 0xa8, 0xc7, 0x47, 0x6e, 0xdb, 0x04, 0xa2, 0xe1, 0xf2, 0x9d, 0xc7, 0x37, 0x22, 0x87, 0x7a, 0xc4, + 0xc1, 0x47, 0x6e, 0xdb, 0x10, 0xaa, 0xe1, 0xf2, 0x9d, 0xc7, 0x9f, 0x88, 0x6b, 0xa2, 0x22, 0xa2, 0x74, 0x80, 0xc1, + 0x2f, 0x6e, 0xdb, 0x0c, 0xac, 0xe1, 0xf2, 0x9d, 0xc7, 0x9f, 0x88, 0x6b, 0xa2, 0x22, 0x82, 0x9d, 0x9c, 0x88, 0xf0, + 0x8b, 0xdb, 0xb6, 0x81, 0x6c, 0xb8, 0x7c, 0xe7, 0xf1, 0xa7, 0x23, 0x22, 0x80, 0x41, 0x1c, 0xc4, 0x06, 0x8c, 0x1c, + 0xea, 0xf1, 0x91, 0xdb, 0xb6, 0x82, 0x67, 0xb8, 0x7c, 0xe7, 0xf1, 0xa9, 0x06, 0x88, 0x30, 0xbf, 0xb8, 0x6d, 0x00, + 0x00, 0x00, 0x00, 0x61, 0x20, 0x00, 0x00, 0x8e, 0x02, 0x00, 0x00, 0x13, 0x04, 0x74, 0x10, 0x0b, 0x04, 0x00, 0x00, + 0x25, 0x00, 0x00, 0x00, 0xd4, 0x94, 0x47, 0x11, 0x8c, 0x00, 0x94, 0x00, 0x19, 0x65, 0x18, 0x50, 0x80, 0x04, 0x05, + 0x1c, 0x50, 0x88, 0x01, 0xa5, 0x18, 0x50, 0x0a, 0xe5, 0x1b, 0x50, 0xbc, 0x01, 0xa5, 0x52, 0xa0, 0x01, 0x33, 0x00, + 0x65, 0x54, 0x76, 0xe5, 0x52, 0x72, 0x45, 0x18, 0x50, 0x6e, 0x85, 0x54, 0x80, 0x02, 0x05, 0x18, 0x50, 0x10, 0x04, + 0x8c, 0x11, 0xd4, 0x6a, 0xad, 0xd6, 0xdf, 0x18, 0x01, 0x08, 0x82, 0x20, 0x0c, 0x06, 0x63, 0x04, 0x7b, 0xac, 0xc6, + 0xfb, 0x37, 0x46, 0x00, 0x82, 0x20, 0x88, 0x7f, 0x63, 0x04, 0x7b, 0xac, 0xc6, 0xfb, 0x2f, 0x8c, 0x11, 0xe0, 0x30, + 0x2f, 0xce, 0xdf, 0x18, 0x01, 0x28, 0xdb, 0xff, 0xc9, 0x8d, 0x11, 0x80, 0x20, 0xfe, 0xdf, 0x63, 0x30, 0x46, 0x80, + 0xb3, 0xf7, 0x99, 0x7b, 0x63, 0x04, 0xb9, 0x5e, 0xba, 0xf3, 0x37, 0x46, 0x00, 0xfb, 0xec, 0x5c, 0x7e, 0x33, 0x00, + 0x23, 0x00, 0x64, 0x0f, 0x75, 0x04, 0x02, 0x60, 0x44, 0x46, 0x34, 0xd4, 0x11, 0x08, 0x80, 0x11, 0x19, 0x10, 0x00, + 0x23, 0x06, 0x09, 0x00, 0x82, 0x60, 0x20, 0x06, 0x7b, 0x60, 0x95, 0x01, 0x1e, 0xe0, 0xc1, 0x1b, 0x8c, 0x18, 0x24, + 0x00, 0x08, 0x82, 0x81, 0x18, 0xf0, 0xc1, 0x65, 0x06, 0x78, 0x80, 0x07, 0x70, 0x30, 0x62, 0x90, 0x00, 0x20, 0x08, + 0x06, 0x62, 0xd0, 0x07, 0x18, 0x1a, 0xe4, 0x41, 0x1e, 0xc4, 0xc1, 0x88, 0x41, 0x02, 0x80, 0x20, 0x18, 0x88, 0x81, + 0x1f, 0x64, 0x6a, 0xa0, 0x07, 0x7a, 0x20, 0x07, 0x23, 0x06, 0x06, 0x00, 0x82, 0x60, 0x70, 0xa8, 0x42, 0x18, 0xec, + 0xc1, 0x88, 0x81, 0x01, 0x80, 0x20, 0x18, 0x1c, 0xab, 0x20, 0x06, 0x7d, 0x30, 0x62, 0x50, 0x00, 0x20, 0x08, 0x06, + 0x89, 0x2a, 0xa0, 0xc1, 0x88, 0xc1, 0x01, 0x80, 0x20, 0x18, 0x7c, 0xa3, 0xf0, 0x11, 0x7f, 0x30, 0x9a, 0x10, 0x08, + 0xc3, 0x0d, 0x01, 0x28, 0x80, 0xc1, 0x88, 0xc1, 0x01, 0x80, 0x20, 0x18, 0x7c, 0xa6, 0x20, 0x06, 0x47, 0x28, 0xcc, + 0x32, 0x04, 0x9b, 0x30, 0x62, 0x60, 0x00, 0x20, 0x08, 0x06, 0x07, 0x2c, 0xa4, 0xc1, 0x28, 0x8c, 0x18, 0x18, 0x00, + 0x08, 0x82, 0xc1, 0x11, 0x0b, 0x6a, 0x30, 0x0a, 0x95, 0xb0, 0xc1, 0x55, 0xd2, 0x06, 0x57, 0x83, 0x00, 0x55, 0x08, + 0x30, 0x9a, 0x70, 0x00, 0xa3, 0x09, 0x48, 0x30, 0xdc, 0x40, 0x08, 0x64, 0x30, 0xdc, 0x40, 0x08, 0x64, 0x50, 0x42, + 0xa0, 0xb3, 0x0c, 0xc2, 0x10, 0x8c, 0x18, 0x34, 0x00, 0x08, 0x82, 0x41, 0x65, 0x0b, 0x6b, 0x40, 0xb5, 0xc2, 0x61, + 0xc0, 0x01, 0x1c, 0xc0, 0x01, 0x1c, 0x8c, 0x26, 0x04, 0xc0, 0x68, 0x82, 0x10, 0x8c, 0x26, 0x0c, 0xc2, 0x88, 0xc1, + 0x01, 0x80, 0x20, 0x18, 0x48, 0xbb, 0x30, 0x07, 0xdd, 0x30, 0x62, 0x70, 0x00, 0x20, 0x08, 0x06, 0x12, 0x2f, 0xd0, + 0x81, 0x37, 0x8c, 0x18, 0x1c, 0x00, 0x08, 0x82, 0x81, 0xd4, 0x0b, 0x75, 0xf0, 0x0d, 0x23, 0x06, 0x07, 0x00, 0x82, + 0x60, 0xc0, 0xe9, 0x42, 0x1d, 0x68, 0xb5, 0x30, 0x9a, 0x10, 0x0c, 0x56, 0x04, 0xf4, 0xb1, 0x42, 0xa0, 0x8f, 0x15, + 0x03, 0x7d, 0x46, 0x0c, 0x16, 0x00, 0x04, 0xc1, 0xe0, 0x0a, 0x07, 0x3b, 0x18, 0x84, 0xe0, 0x0c, 0xd0, 0x20, 0x0d, + 0x46, 0x0c, 0x0e, 0x00, 0x04, 0xc1, 0x40, 0x22, 0x07, 0x3b, 0x08, 0xd6, 0x60, 0xc4, 0xe0, 0x00, 0x40, 0x10, 0x0c, + 0xa4, 0x72, 0xe8, 0x83, 0x36, 0x08, 0x46, 0x0c, 0x0c, 0x00, 0x04, 0xc1, 0x60, 0x41, 0x07, 0x3e, 0x08, 0x2c, 0x80, + 0x03, 0xf9, 0xcc, 0x12, 0x0c, 0x03, 0x15, 0x80, 0x20, 0xd0, 0x42, 0x50, 0x19, 0x2e, 0xc0, 0x70, 0x43, 0x80, 0x91, + 0x41, 0x05, 0x96, 0xce, 0x32, 0x10, 0x45, 0x30, 0x62, 0xd0, 0x00, 0x20, 0x08, 0x06, 0xd5, 0x3a, 0x80, 0x42, 0x1a, + 0x88, 0xc3, 0xb0, 0x95, 0x42, 0x29, 0x94, 0x42, 0x29, 0x8c, 0x26, 0x04, 0xc0, 0x68, 0x82, 0x10, 0x8c, 0x26, 0x0c, + 0xc2, 0x88, 0xc1, 0x01, 0x80, 0x20, 0x18, 0x48, 0xf0, 0x80, 0x0a, 0x72, 0x30, 0x8c, 0x18, 0x1c, 0x00, 0x08, 0x82, + 0x81, 0x14, 0x0f, 0xa9, 0x30, 0x07, 0xc3, 0x88, 0xc1, 0x01, 0x80, 0x20, 0x18, 0x48, 0xf2, 0xa0, 0x0a, 0x74, 0x30, + 0x8c, 0x18, 0x1c, 0x00, 0x08, 0x82, 0x01, 0xf7, 0x0e, 0xaa, 0xf0, 0x06, 0xea, 0x30, 0x9a, 0x10, 0x0c, 0x56, 0x04, + 0xf4, 0xb1, 0x42, 0xa0, 0x8f, 0x15, 0x03, 0x7d, 0x46, 0x0c, 0x16, 0x00, 0x04, 0xc1, 0xe0, 0xb2, 0x87, 0x55, 0x18, + 0x84, 0x80, 0x0f, 0xfa, 0xc0, 0x0f, 0x46, 0x0c, 0x0e, 0x00, 0x04, 0xc1, 0x40, 0xca, 0x87, 0x55, 0x08, 0x40, 0x61, + 0xc4, 0xe0, 0x00, 0x40, 0x10, 0x0c, 0x24, 0x7d, 0x90, 0x05, 0x51, 0x08, 0x46, 0x0c, 0x0c, 0x00, 0x04, 0xc1, 0x60, + 0xe9, 0x87, 0x58, 0x08, 0x2c, 0x28, 0x05, 0xf9, 0x58, 0x50, 0xc1, 0x67, 0x96, 0xa0, 0x18, 0xa8, 0x00, 0x04, 0x82, + 0x0d, 0x86, 0x72, 0x03, 0x77, 0x80, 0xe1, 0x86, 0xa0, 0x0d, 0xc8, 0xa0, 0xda, 0x20, 0xd0, 0x59, 0x06, 0xe3, 0x08, + 0x46, 0x0c, 0x1a, 0x00, 0x04, 0xc1, 0xa0, 0x0a, 0x09, 0x5b, 0xf8, 0x03, 0x7c, 0x90, 0x83, 0x61, 0x17, 0x76, 0x61, + 0x17, 0x76, 0x61, 0x34, 0x21, 0x00, 0x46, 0x13, 0x84, 0x60, 0x34, 0x61, 0x10, 0x46, 0x0c, 0x0e, 0x00, 0x04, 0xc1, + 0x40, 0x32, 0x09, 0x5f, 0x40, 0x85, 0x61, 0xc4, 0xe0, 0x00, 0x40, 0x10, 0x0c, 0xa4, 0x93, 0xf8, 0x85, 0x54, 0x18, + 0x46, 0x0c, 0x0e, 0x00, 0x04, 0xc1, 0x40, 0x42, 0x09, 0x70, 0x50, 0x85, 0x61, 0xc4, 0xe0, 0x00, 0x40, 0x10, 0x0c, + 0xb8, 0x92, 0x00, 0x87, 0x52, 0x00, 0x89, 0xd1, 0x84, 0x60, 0xb0, 0x22, 0xa0, 0x8f, 0x15, 0x02, 0x7d, 0xac, 0x18, + 0xe8, 0x33, 0x62, 0xb0, 0x00, 0x20, 0x08, 0x06, 0x17, 0x4b, 0x84, 0xc3, 0x20, 0x04, 0xb2, 0x30, 0x0b, 0xb4, 0x30, + 0x62, 0x70, 0x00, 0x20, 0x08, 0x06, 0xd2, 0x4b, 0x84, 0x43, 0x60, 0x0b, 0x23, 0x06, 0x07, 0x00, 0x82, 0x60, 0x20, + 0xc1, 0x04, 0x3a, 0xe0, 0x42, 0x30, 0x62, 0x60, 0x00, 0x20, 0x08, 0x06, 0xcb, 0x4c, 0x9c, 0x43, 0x60, 0xc1, 0x2e, + 0xc8, 0xc7, 0x82, 0x0a, 0x3e, 0xb3, 0x04, 0xc7, 0x40, 0x05, 0x20, 0x18, 0x6c, 0x50, 0xd4, 0x1a, 0x54, 0x3a, 0xcb, + 0x80, 0x24, 0xc1, 0x88, 0x41, 0x03, 0x80, 0x20, 0x18, 0x54, 0x35, 0xa1, 0x0e, 0xb3, 0xc0, 0x12, 0x6d, 0x70, 0xbd, + 0xc3, 0x3b, 0xbc, 0xc3, 0x3b, 0x8c, 0x26, 0x04, 0xc0, 0x68, 0x82, 0x10, 0x8c, 0x26, 0x0c, 0xc2, 0x88, 0xc1, 0x01, + 0x80, 0x20, 0x18, 0x48, 0x3a, 0x21, 0x0f, 0xbc, 0x30, 0x8c, 0x18, 0x1c, 0x00, 0x08, 0x82, 0x81, 0xb4, 0x13, 0xf3, + 0xd0, 0x0b, 0xc3, 0x88, 0xc1, 0x01, 0x80, 0x20, 0x18, 0x48, 0x3c, 0x41, 0x0f, 0xbe, 0x30, 0x8c, 0x18, 0x1c, 0x00, + 0x08, 0x82, 0x01, 0x97, 0x13, 0xf4, 0x90, 0x0b, 0x34, 0x31, 0x9a, 0x10, 0x0c, 0x56, 0x04, 0xf4, 0xb1, 0x42, 0xa0, + 0x8f, 0x15, 0x03, 0x7d, 0x46, 0x0c, 0x16, 0x00, 0x04, 0xc1, 0xe0, 0x02, 0x8b, 0x7a, 0x18, 0x84, 0xc0, 0x1c, 0xce, + 0x01, 0x1d, 0x46, 0x0c, 0x0e, 0x00, 0x04, 0xc1, 0x40, 0x1a, 0x8b, 0x7a, 0x08, 0xd4, 0x61, 0xc4, 0xe0, 0x00, 0x40, + 0x10, 0x0c, 0x24, 0xb2, 0xe0, 0x07, 0x76, 0x08, 0x46, 0x0c, 0x0c, 0x00, 0x04, 0xc1, 0x60, 0x39, 0x8b, 0x7d, 0x08, + 0x2c, 0x78, 0x07, 0xf9, 0x58, 0x30, 0xc1, 0x67, 0x96, 0x20, 0x19, 0xa8, 0x00, 0x04, 0x04, 0x0d, 0x8e, 0x15, 0x0c, + 0x70, 0xf1, 0x13, 0xe2, 0x30, 0x6c, 0x40, 0x04, 0xc2, 0x00, 0x8c, 0x18, 0x18, 0x00, 0x08, 0x82, 0x41, 0x76, 0x16, + 0x24, 0xf1, 0x13, 0xc3, 0x0d, 0xe3, 0xb0, 0x0f, 0x64, 0x30, 0xcb, 0xa0, 0x2c, 0x41, 0x91, 0x03, 0x3f, 0xc0, 0x0a, + 0x86, 0xb9, 0x10, 0x8b, 0x80, 0x02, 0x60, 0x50, 0x01, 0x0c, 0x0b, 0x04, 0xf8, 0x0c, 0x1b, 0x10, 0x47, 0x30, 0x00, + 0xb3, 0x04, 0xcb, 0x88, 0x81, 0x01, 0x80, 0x20, 0x18, 0x64, 0x6d, 0xa1, 0x12, 0x65, 0x31, 0xdc, 0x90, 0x0e, 0x20, + 0x41, 0x06, 0xb3, 0x0c, 0x4c, 0x13, 0x94, 0x3a, 0x84, 0x04, 0xac, 0x60, 0xc8, 0x0b, 0xb4, 0x08, 0x28, 0x00, 0x06, + 0x2d, 0xc0, 0xb0, 0x40, 0x80, 0xcf, 0xb0, 0x01, 0xd1, 0x04, 0x03, 0x30, 0x4b, 0xd0, 0x8c, 0x18, 0x18, 0x00, 0x08, + 0x82, 0x41, 0x36, 0x17, 0x30, 0xb1, 0x16, 0xc3, 0x0d, 0xef, 0x60, 0x16, 0x64, 0x30, 0xcb, 0xe0, 0x3c, 0x41, 0xc1, + 0xc3, 0x59, 0xc0, 0x0a, 0x86, 0xbf, 0x70, 0x8b, 0x80, 0x02, 0x60, 0x50, 0x04, 0x0c, 0x0b, 0x04, 0xf8, 0x0c, 0x1b, + 0x10, 0x53, 0x30, 0x00, 0xb3, 0x04, 0xcf, 0x88, 0x81, 0x01, 0x80, 0x20, 0x18, 0x64, 0x79, 0x61, 0x13, 0x71, 0x31, + 0xdc, 0x50, 0x0f, 0x6b, 0x41, 0x06, 0xb3, 0x0c, 0x50, 0x14, 0x94, 0x3d, 0xb0, 0x05, 0xac, 0x60, 0x28, 0x0d, 0xba, + 0x08, 0x28, 0x00, 0x06, 0x5d, 0xc0, 0xb0, 0x40, 0x80, 0xcf, 0xb0, 0x01, 0x91, 0x05, 0x03, 0x30, 0x4b, 0x10, 0x8d, + 0x18, 0x18, 0x00, 0x08, 0x82, 0x41, 0xf6, 0x17, 0x3c, 0x71, 0x17, 0xc3, 0x0d, 0xfb, 0x10, 0x13, 0x64, 0x30, 0xcb, + 0x20, 0x4d, 0x41, 0xf1, 0x83, 0x4c, 0xc0, 0x0a, 0x86, 0xd5, 0xd0, 0x8b, 0x80, 0x02, 0x60, 0x50, 0x07, 0x0c, 0x0b, + 0x04, 0xf8, 0x0c, 0x1b, 0x10, 0x5f, 0x30, 0x00, 0xb3, 0x04, 0xd3, 0x88, 0x81, 0x01, 0x80, 0x20, 0x18, 0x64, 0xa5, + 0x21, 0x16, 0x7d, 0x31, 0xdc, 0x10, 0x12, 0x79, 0x41, 0x06, 0xb3, 0x0c, 0x54, 0x15, 0x94, 0x48, 0xe8, 0x05, 0xac, + 0x60, 0x88, 0x0d, 0xd0, 0x08, 0x28, 0x00, 0x06, 0x8d, 0x01, 0x30, 0x2c, 0x10, 0xe0, 0x33, 0x6c, 0x40, 0x94, 0x41, + 0x30, 0x00, 0xb3, 0x04, 0xd5, 0x88, 0x81, 0x01, 0x80, 0x20, 0x18, 0x64, 0xab, 0x81, 0x16, 0xa3, 0x31, 0xdc, 0x70, + 0x12, 0xa1, 0x41, 0x06, 0xb3, 0x0c, 0xd6, 0x15, 0x14, 0x4a, 0x88, 0x06, 0xac, 0x60, 0xb8, 0x0d, 0xd3, 0x08, 0x28, + 0x00, 0x06, 0xa5, 0x01, 0x30, 0x2c, 0x10, 0xe0, 0x33, 0x6c, 0x40, 0xac, 0x41, 0x30, 0x00, 0xb3, 0x04, 0xd7, 0x88, + 0x81, 0x01, 0x80, 0x20, 0x18, 0x64, 0xb1, 0xe1, 0x16, 0xa9, 0x31, 0xdc, 0xd0, 0x12, 0xaa, 0x01, 0x06, 0xb3, 0x0c, + 0x58, 0x16, 0x50, 0x4d, 0x00, 0x83, 0x6e, 0x02, 0x18, 0x16, 0x08, 0xf0, 0x19, 0x36, 0x20, 0x72, 0x22, 0x18, 0x80, + 0x59, 0x82, 0x6c, 0xa0, 0x22, 0x0c, 0x10, 0x8c, 0x65, 0xae, 0x11, 0x03, 0x03, 0x00, 0x41, 0x30, 0xc8, 0x6c, 0x63, + 0x2e, 0x5c, 0x63, 0x96, 0x41, 0x9b, 0x83, 0x80, 0x74, 0x02, 0x18, 0x23, 0x06, 0x07, 0x00, 0x82, 0x60, 0xf0, 0xd5, + 0x46, 0x5c, 0xd8, 0x04, 0x6c, 0x8c, 0x26, 0x04, 0x42, 0x05, 0x36, 0x21, 0x85, 0x13, 0xb4, 0x01, 0x15, 0x08, 0x30, + 0x62, 0xd0, 0x00, 0x20, 0x08, 0x06, 0x64, 0x80, 0x1b, 0x7e, 0xd1, 0x13, 0x41, 0x6d, 0x18, 0x62, 0x21, 0x16, 0x62, + 0x31, 0x1a, 0xb3, 0x04, 0x73, 0x30, 0x9a, 0x40, 0x13, 0xc3, 0x70, 0x43, 0x4e, 0x04, 0x64, 0x30, 0xcb, 0xc0, 0x7d, + 0xc1, 0x2c, 0x41, 0x37, 0x50, 0x01, 0x2c, 0x9d, 0xa9, 0x70, 0x03, 0x15, 0xc6, 0xd2, 0xd9, 0x09, 0x57, 0x81, 0x6e, + 0xc0, 0x88, 0x01, 0x02, 0x80, 0x20, 0x18, 0x98, 0x01, 0x6f, 0x90, 0x86, 0x58, 0x04, 0xba, 0x31, 0x9a, 0x10, 0x00, + 0x16, 0x14, 0xf0, 0xa9, 0x22, 0x35, 0x60, 0xc4, 0xe0, 0x00, 0x40, 0x10, 0x0c, 0xbe, 0xf1, 0xf8, 0x0b, 0xb2, 0xf0, + 0x8d, 0xd1, 0x84, 0x60, 0x18, 0x6e, 0x18, 0x02, 0x32, 0x98, 0x65, 0xe8, 0xbc, 0x60, 0x96, 0xe0, 0x1b, 0xa8, 0x00, + 0x74, 0x65, 0x53, 0xbc, 0x15, 0x0c, 0xf3, 0x21, 0x1e, 0x65, 0x31, 0x6c, 0x40, 0x04, 0xc2, 0x00, 0x8c, 0x18, 0x18, + 0x00, 0x08, 0x82, 0x41, 0xa6, 0x1e, 0xa7, 0x21, 0x1e, 0xc3, 0x0d, 0x66, 0xe1, 0x17, 0x64, 0x30, 0xcb, 0x00, 0x06, + 0x61, 0x10, 0xd4, 0x59, 0xfc, 0x05, 0xac, 0x60, 0xb0, 0x8f, 0xf2, 0x08, 0x28, 0x00, 0x06, 0x15, 0xc0, 0xb0, 0x40, + 0x80, 0xcf, 0xb0, 0x01, 0x71, 0x04, 0x03, 0x30, 0x4b, 0x10, 0x06, 0x23, 0x06, 0x06, 0x00, 0x82, 0x60, 0x90, 0xc1, + 0x47, 0x6b, 0xa0, 0xc7, 0x70, 0x03, 0x5b, 0x8c, 0x06, 0x19, 0xcc, 0x32, 0x88, 0xc1, 0x18, 0x04, 0xd5, 0x16, 0xa4, + 0x01, 0x2b, 0x18, 0xf8, 0x63, 0x3d, 0x02, 0x0a, 0x80, 0x41, 0x0b, 0x30, 0x2c, 0x10, 0xe0, 0x33, 0x6c, 0x40, 0x34, + 0xc1, 0x00, 0xcc, 0x12, 0x8c, 0xc1, 0x88, 0x81, 0x01, 0x80, 0x20, 0x18, 0x64, 0xf6, 0x31, 0x1b, 0xee, 0x31, 0xdc, + 0x20, 0x17, 0xe9, 0x41, 0x06, 0xb3, 0x0c, 0x64, 0x50, 0x06, 0x41, 0xcd, 0x85, 0x7a, 0xc0, 0x0a, 0x06, 0x11, 0x89, + 0x8f, 0x80, 0x02, 0x60, 0x50, 0x04, 0x0c, 0x0b, 0x04, 0xf8, 0x0c, 0x1b, 0x10, 0x53, 0x30, 0x00, 0xb3, 0x04, 0x65, + 0x30, 0x62, 0x60, 0x00, 0x20, 0x08, 0x06, 0x19, 0x7f, 0xe4, 0x06, 0x7d, 0x0c, 0x37, 0xe0, 0x85, 0x7b, 0x90, 0xc1, + 0x2c, 0x83, 0x19, 0x9c, 0x41, 0x50, 0x79, 0xf1, 0x1e, 0xb0, 0x82, 0x01, 0x45, 0xee, 0x23, 0xa0, 0x00, 0x18, 0x74, + 0x01, 0xc3, 0x02, 0x01, 0x3e, 0xc3, 0x06, 0x44, 0x16, 0x0c, 0xc0, 0x2c, 0xc1, 0x19, 0x8c, 0x18, 0x18, 0x00, 0x08, + 0x82, 0x41, 0x26, 0x22, 0xbf, 0xa1, 0x1f, 0xc3, 0x0d, 0x7e, 0x41, 0x1b, 0x64, 0x30, 0xcb, 0x80, 0x06, 0x69, 0x10, + 0xd4, 0x5f, 0xd4, 0x06, 0xac, 0x60, 0x70, 0x91, 0xfe, 0x08, 0x28, 0x00, 0x06, 0x75, 0xc0, 0xb0, 0x40, 0x80, 0xcf, + 0xb0, 0x01, 0xf1, 0x05, 0x03, 0x30, 0x4b, 0x90, 0x06, 0x23, 0x06, 0x06, 0x00, 0x82, 0x60, 0x90, 0xa1, 0x48, 0x79, + 0x80, 0xc8, 0x70, 0x03, 0x69, 0xf0, 0x07, 0x19, 0xcc, 0x32, 0xa8, 0xc1, 0x1a, 0x04, 0x55, 0x1a, 0xfd, 0x01, 0x2b, + 0x18, 0x68, 0x64, 0x44, 0x02, 0x0a, 0x80, 0x41, 0x63, 0x00, 0x0c, 0x0b, 0x04, 0xf8, 0x0c, 0x1b, 0x10, 0x65, 0x10, + 0x0c, 0xc0, 0x2c, 0xc1, 0x1a, 0x8c, 0x18, 0x18, 0x00, 0x08, 0x82, 0x41, 0xe6, 0x22, 0xeb, 0x61, 0x22, 0xc3, 0x0d, + 0xaa, 0x41, 0x22, 0x64, 0x30, 0xcb, 0xc0, 0x06, 0x6d, 0x10, 0xd4, 0x6a, 0x94, 0x08, 0xac, 0x60, 0xd0, 0x91, 0x14, + 0x09, 0x28, 0x00, 0x06, 0xa5, 0x01, 0x30, 0x2c, 0x10, 0xe0, 0x33, 0x6c, 0x40, 0xac, 0x41, 0x30, 0x00, 0xb3, 0x04, + 0x6d, 0x30, 0x62, 0x60, 0x00, 0x20, 0x08, 0x06, 0x19, 0x8d, 0xc4, 0x07, 0x8b, 0x0c, 0x37, 0xc0, 0x46, 0x8b, 0x80, + 0xc1, 0x2c, 0x83, 0x1b, 0xbc, 0x41, 0x40, 0xb8, 0x01, 0x0c, 0xd2, 0x0d, 0x60, 0x58, 0x20, 0xc0, 0x67, 0xd8, 0x80, + 0xe0, 0x8d, 0x60, 0x00, 0x66, 0x09, 0xde, 0x60, 0xa0, 0x22, 0x0c, 0x10, 0x37, 0x90, 0xa1, 0x36, 0x18, 0x31, 0x30, + 0x00, 0x10, 0x04, 0x83, 0x2c, 0x47, 0xec, 0x23, 0x46, 0x66, 0x19, 0xe0, 0x60, 0x0e, 0x02, 0xea, 0x0d, 0x60, 0x8c, + 0x18, 0x1c, 0x00, 0x08, 0x82, 0xc1, 0x87, 0x23, 0xf4, 0x91, 0x1b, 0x33, 0x32, 0x9a, 0x10, 0x00, 0x17, 0x00, 0x35, + 0x9a, 0x30, 0x04, 0x17, 0x00, 0x65, 0xc1, 0x20, 0x1f, 0x3b, 0x02, 0xfa, 0x8c, 0x18, 0x1c, 0x00, 0x08, 0x82, 0xc1, + 0xf7, 0x23, 0xfb, 0x01, 0x1e, 0x3b, 0x32, 0x9a, 0x10, 0x04, 0xc3, 0x0d, 0x01, 0x8f, 0x80, 0xc1, 0x2c, 0x43, 0x1c, + 0xc8, 0x41, 0x30, 0x62, 0x80, 0x00, 0x20, 0x08, 0x06, 0x66, 0xf0, 0x23, 0x27, 0x52, 0x1e, 0x3d, 0xd2, 0x23, 0xa3, + 0x09, 0x01, 0x60, 0x46, 0x10, 0x9f, 0x11, 0x83, 0x03, 0x00, 0x41, 0x30, 0xe0, 0xcc, 0x24, 0x44, 0xcc, 0x23, 0x4c, + 0x46, 0x13, 0x02, 0xc0, 0x02, 0xfb, 0x90, 0xcf, 0x88, 0x81, 0x01, 0x80, 0x20, 0x18, 0x2c, 0x6f, 0x82, 0x22, 0x81, + 0xe5, 0x47, 0x10, 0x1f, 0x0b, 0x0c, 0xf9, 0x58, 0x80, 0xc0, 0x67, 0x96, 0x40, 0x0e, 0x06, 0x2a, 0x00, 0x21, 0x0e, + 0x38, 0x38, 0x18, 0x31, 0x68, 0x00, 0x10, 0x04, 0x03, 0x32, 0x58, 0x93, 0x18, 0x81, 0x0f, 0x34, 0x41, 0x93, 0xa0, + 0x3e, 0xea, 0xa3, 0x3e, 0x6c, 0xc4, 0x02, 0xff, 0x90, 0xcf, 0x88, 0x81, 0x01, 0x80, 0x20, 0x18, 0x2c, 0x75, 0xe2, + 0x22, 0x81, 0x05, 0x21, 0x22, 0x9f, 0x11, 0x03, 0x03, 0x00, 0x41, 0x30, 0x58, 0xee, 0x64, 0x45, 0x82, 0x11, 0x03, + 0x03, 0x00, 0x41, 0x30, 0x58, 0xf0, 0x24, 0x46, 0x02, 0x2b, 0x91, 0x80, 0x3e, 0x23, 0x06, 0x0e, 0x00, 0x82, 0x60, + 0x00, 0xe5, 0xc9, 0x8e, 0xdc, 0x87, 0x9b, 0xb8, 0x49, 0x8c, 0x04, 0x41, 0x10, 0xfc, 0xc8, 0x2c, 0xc1, 0x1c, 0x60, + 0x40, 0x0c, 0x00, 0x00, 0x00, 0x4a, 0x00, 0x00, 0x00, 0x5b, 0x06, 0x79, 0x08, 0xd8, 0x60, 0xcb, 0x80, 0x0f, 0x01, + 0x1b, 0x6c, 0x19, 0xf2, 0x21, 0x60, 0x83, 0x2d, 0xc3, 0x3e, 0x04, 0x6c, 0xb0, 0x65, 0x10, 0x89, 0x80, 0x0d, 0xb6, + 0x0c, 0x23, 0x11, 0xb0, 0xc1, 0x96, 0xa1, 0x24, 0x02, 0x36, 0xd8, 0x32, 0xb0, 0x44, 0xc0, 0x06, 0x5b, 0x86, 0x96, + 0x08, 0xd8, 0x60, 0xcb, 0xf0, 0x12, 0x01, 0x1b, 0x6c, 0x19, 0x6c, 0x22, 0x60, 0x83, 0x2d, 0xc3, 0x4d, 0x04, 0x6c, + 0xb0, 0x65, 0xc8, 0x89, 0x80, 0x0d, 0xb6, 0x0c, 0x60, 0x11, 0xb0, 0xc1, 0x96, 0x21, 0x2c, 0x02, 0x36, 0xd8, 0x32, + 0x8c, 0x45, 0xc0, 0x06, 0x5b, 0x06, 0xb5, 0x08, 0xd8, 0x60, 0xcb, 0xb0, 0x16, 0x01, 0x1b, 0x6c, 0x19, 0xda, 0x22, + 0x60, 0x83, 0x2d, 0x03, 0x5d, 0x04, 0x6c, 0xb0, 0x65, 0xa8, 0x8b, 0x80, 0x0d, 0xb6, 0x0c, 0x77, 0x11, 0xb0, 0xc1, + 0x96, 0x81, 0x2f, 0x02, 0x36, 0xd8, 0x32, 0xf4, 0x45, 0xc0, 0x06, 0x5b, 0x86, 0xbf, 0x08, 0xd8, 0x60, 0xcb, 0x40, + 0x1a, 0x01, 0x1b, 0x6c, 0x19, 0x7c, 0x23, 0x60, 0x83, 0x2d, 0x03, 0x79, 0x04, 0x6c, 0xb0, 0x65, 0x28, 0x8f, 0x80, + 0x0d, 0xb6, 0x0c, 0xe7, 0x11, 0xb0, 0xc1, 0x96, 0xc1, 0x3d, 0x02, 0x36, 0xd8, 0x32, 0xbc, 0x47, 0xc0, 0x06, 0x5b, + 0x86, 0xf8, 0x08, 0xd8, 0x60, 0xcb, 0x80, 0x1f, 0x01, 0x1b, 0x6c, 0x19, 0xf2, 0x23, 0x60, 0x83, 0x2d, 0xc3, 0x7e, + 0x04, 0x6c, 0xb0, 0x65, 0x10, 0x91, 0x80, 0x0d, 0xb6, 0x0c, 0x23, 0x12, 0xb0, 0xc1, 0x96, 0xa1, 0x44, 0x02, 0x36, + 0xd8, 0x32, 0xb0, 0x48, 0xc0, 0x06, 0x5b, 0x86, 0x16, 0x09, 0xd8, 0x60, 0xcb, 0xf0, 0x22, 0x01, 0x1b, 0x6c, 0x19, + 0x6c, 0x24, 0x60, 0x83, 0x2d, 0xc3, 0x8d, 0x04, 0x6c, 0xb0, 0x65, 0xc8, 0x91, 0x80, 0x0d, 0xb6, 0x0c, 0x60, 0x12, + 0xb0, 0xc1, 0x96, 0x21, 0x4c, 0x02, 0x36, 0xd8, 0x32, 0x8c, 0x49, 0xc0, 0x06, 0x5b, 0x06, 0x34, 0x09, 0xd8, 0x60, + 0xcb, 0x90, 0x26, 0x01, 0x1b, 0x6c, 0x19, 0xd6, 0x24, 0x60, 0x83, 0x2d, 0x03, 0x9c, 0x04, 0x6c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; diff --git a/OptiScaler/upscalers/ffx/FFXFeature_Dx12.cpp b/OptiScaler/upscalers/ffx/FFXFeature_Dx12.cpp index 1f6cac64..e61dd06b 100644 --- a/OptiScaler/upscalers/ffx/FFXFeature_Dx12.cpp +++ b/OptiScaler/upscalers/ffx/FFXFeature_Dx12.cpp @@ -38,57 +38,6 @@ bool FFXFeatureDx12::InitInternal(ID3D12GraphicsCommandList* InCommandList, NVSD return InitFFX(InParameters); } -bool CreateBufferResourceWithSize(ID3D12Device* device, ID3D12Resource* source, D3D12_RESOURCE_STATES state, - ID3D12Resource** target, UINT width, UINT height) -{ - if (device == nullptr || source == nullptr) - return false; - - auto inDesc = source->GetDesc(); - - if (*target != nullptr) - { - auto bufDesc = (*target)->GetDesc(); - - if (bufDesc.Width != width || bufDesc.Height != height || bufDesc.Format != inDesc.Format || - bufDesc.Flags != inDesc.Flags) - { - // Previous frames can still be using it - DeferredRelease::Release(*target); - } - else - { - return true; - } - } - - D3D12_HEAP_PROPERTIES heapProperties; - D3D12_HEAP_FLAGS heapFlags; - HRESULT hr = source->GetHeapProperties(&heapProperties, &heapFlags); - - if (hr != S_OK) - { - LOG_ERROR("GetHeapProperties result: {:X}", (UINT64) hr); - return false; - } - - inDesc.Width = width; - inDesc.Height = height; - - hr = device->CreateCommittedResource(&heapProperties, D3D12_HEAP_FLAG_NONE, &inDesc, state, nullptr, - IID_PPV_ARGS(target)); - - if (hr != S_OK) - { - LOG_ERROR("CreateCommittedResource result: {:X}", (UINT64) hr); - return false; - } - - LOG_DEBUG("Created new one: {}x{}", inDesc.Width, inDesc.Height); - - return true; -} - bool FFXFeatureDx12::EvaluateInternal(ID3D12GraphicsCommandList* InCommandList, NVSDK_NGX_Parameter* InParameters) { LOG_FUNC(); @@ -161,70 +110,6 @@ bool FFXFeatureDx12::EvaluateInternal(ID3D12GraphicsCommandList* InCommandList, D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE); } - // WAR for FSR 4's autoexposure shader reading entire underlying resource - // instead of what's specified by renderSize or color's FfxApiResourceDescription. - // Only linear has this issue - if (Version().major >= 4 && AutoExposure() && !Config::Instance()->FsrNonLinearPQ.value_or_default() && - !Config::Instance()->FsrNonLinearSRGB.value_or_default() && - !Config::Instance()->FsrNonLinearColorSpace.value_or_default()) - { - D3D12_RESOURCE_DESC desc = paramColor->GetDesc(); - - const auto diffW = static_cast(desc.Width) - static_cast(params.renderSize.width); - const auto diffH = static_cast(desc.Height) - static_cast(params.renderSize.height); - - // Seemingly it may only be happening when both axes are 1 pixel too big - // But let's be conservative here and also trigger when just one axis is too big - const bool validW = (diffW >= 0 && diffW <= 2); - const bool validH = (diffH >= 0 && diffH <= 2); - const bool isPadded = (diffW > 0 || diffH > 0); - - if (validW && validH && isPadded) - { - static size_t count = 0; - const size_t index = count % 2; - - CreateBufferResourceWithSize(Device, paramColor, D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE, - &smallerColor[index], params.renderSize.width, params.renderSize.height); - - if (smallerColor[index]) - { - ResourceBarrier(InCommandList, paramColor, D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE, - D3D12_RESOURCE_STATE_COPY_SOURCE); - - ResourceBarrier(InCommandList, smallerColor[index], D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE, - D3D12_RESOURCE_STATE_COPY_DEST); - - D3D12_BOX srcBox {}; - srcBox.left = 0; - srcBox.top = 0; - srcBox.right = params.renderSize.width; - srcBox.bottom = params.renderSize.height; - srcBox.front = 0; - srcBox.back = 1; - - D3D12_TEXTURE_COPY_LOCATION dstLocation {}; - dstLocation.pResource = smallerColor[index]; - dstLocation.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX; - dstLocation.SubresourceIndex = 0; - - D3D12_TEXTURE_COPY_LOCATION srcLocation {}; - srcLocation.pResource = paramColor; - srcLocation.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX; - srcLocation.SubresourceIndex = 0; - - InCommandList->CopyTextureRegion(&dstLocation, 0, 0, 0, &srcLocation, &srcBox); - - ResourceBarrier(InCommandList, smallerColor[index], D3D12_RESOURCE_STATE_COPY_DEST, - D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE); - - paramColor = smallerColor[index]; - } - - count++; - } - } - params.color = ffxApiGetResourceDX12(paramColor, FFX_API_RESOURCE_STATE_COMPUTE_READ); } else @@ -579,6 +464,19 @@ bool FFXFeatureDx12::EvaluateInternal(ID3D12GraphicsCommandList* InCommandList, params.upscaleSize.height = TargetHeight(); } + if (_customAutoExposure) + { + if (_autoExposure->Dispatch(InCommandList, paramColor, params.renderSize.width, params.renderSize.height, + params.preExposure, params.frameTimeDelta / 1000.0f, params.reset)) + { + params.exposure = ffxApiGetResourceDX12(_autoExposure->Exposure(), FFX_API_RESOURCE_STATE_COMPUTE_READ); + } + else + { + LOG_ERROR("Auto exposure dispatch failed"); + } + } + LOG_DEBUG("Dispatch!!"); auto result = FfxApiProxy::D3D12_Dispatch(&_context, ¶ms.header); @@ -663,12 +561,36 @@ bool FFXFeatureDx12::InitFFX(const NVSDK_NGX_Parameter* InParameters) State::Instance().ffxUpscalerVersionsDx12.ids.size()) Config::Instance()->FfxUpscalerIndex.set_volatile_value(0); + parse_version( + State::Instance().ffxUpscalerVersionsDx12.names[Config::Instance()->FfxUpscalerIndex.value_or_default()]); + ffxOverrideVersion override = { 0 }; override.header.type = FFX_API_DESC_TYPE_OVERRIDE_VERSION; override.versionId = State::Instance().ffxUpscalerVersionsDx12.ids[Config::Instance()->FfxUpscalerIndex.value_or_default()]; backendDesc.header.pNext = &override.header; + // FSR4's own auto exposure reads the whole color texture instead of just renderSize. On UE the padding + // outside the view can hold garbage that makes it think the scene is very bright and black out the frame. + // Run our own auto exposure instead and hand FSR4 the result as a regular exposure texture. + // Only linear input is affected, color space changes recreate the feature. + _customAutoExposure = false; + auto& cfg = *Config::Instance(); + + if (Version().major >= 4 && AutoExposure() && !cfg.FsrNonLinearPQ.value_or_default() && + !cfg.FsrNonLinearSRGB.value_or_default() && !cfg.FsrNonLinearColorSpace.value_or_default()) + { + if (_autoExposure == nullptr) + _autoExposure = std::make_unique("AutoExposure", Device); + + if (_autoExposure->IsInit()) + { + _customAutoExposure = true; + _contextDesc.flags &= ~FFX_UPSCALE_ENABLE_AUTO_EXPOSURE; + LOG_INFO("Using OptiScaler auto exposure instead of FSR's"); + } + } + LOG_DEBUG("_createContext!"); { @@ -683,10 +605,7 @@ bool FFXFeatureDx12::InitFFX(const NVSDK_NGX_Parameter* InParameters) } } - auto version = - State::Instance().ffxUpscalerVersionsDx12.names[Config::Instance()->FfxUpscalerIndex.value_or_default()]; _name = "FSR"; - parse_version(version); } SetInit(true); diff --git a/OptiScaler/upscalers/ffx/FFXFeature_Dx12.h b/OptiScaler/upscalers/ffx/FFXFeature_Dx12.h index 885085b4..debcac0f 100644 --- a/OptiScaler/upscalers/ffx/FFXFeature_Dx12.h +++ b/OptiScaler/upscalers/ffx/FFXFeature_Dx12.h @@ -4,11 +4,13 @@ #include "dx12/ffx_api_dx12.h" #include "proxies/FfxApi_Proxy.h" +#include class FFXFeatureDx12 : public FFXFeature, public IFeature_Dx12 { private: - ID3D12Resource* smallerColor[2] {}; + std::unique_ptr _autoExposure; + bool _customAutoExposure = false; NVSDK_NGX_Parameter* SetParameters(NVSDK_NGX_Parameter* InParameters); @@ -44,8 +46,5 @@ class FFXFeatureDx12 : public FFXFeature, public IFeature_Dx12 if (_context != nullptr) FfxApiProxy::D3D12_DestroyContext(&_context, NULL); - - SAFE_RELEASE(smallerColor[0]); - SAFE_RELEASE(smallerColor[1]); } };